Consider the following code:
#include <iostream>
#include <cstdlib>
#include <ctime>
struct BaseClass {
static int identifier() {
static int identifier_counter = 0;
return identifier_counter++;
}
};
template <class D>
struct Class: public BaseClass {
static int identifier() {
static int class_identifier = BaseClass::identifier();
return class_identifier;
}
};
struct A: public Class<A> { };
struct B: public Class<B> { };
int main() {
std::srand(std::time(0));
int r = std::rand()%2;
if(r) {
std::cout << "A: " << A::identifier() << std::endl;
std::cout << "B: " << B::identifier() << std::endl;
} else {
std::cout << "B: " << B::identifier() << std::endl;
std::cout << "A: " << A::identifier() << std::endl;
}
}
It's a reduced, but still plausible representation of the problem.
Any derived class will have a specific, different identifier on runtime and two instances of the same type will share the same identifier. Surely a good solution for such a problem.
Unfortunately, those identifiers depend on the order on which the identifier members are invoked (we can see it easily by running multiple times the example). In other words, given two classes A and B, if it happens that running twice the software their identifier members are invoked in different order, they have different identifiers.
My problem is that, for some reasons, I need to store those identifiers somewhere and let them survive the single execution, so that I can reason on the original types once the application runs once more and decide to read those values from the storage.
An alternative would be to use hash_code from type_info, but it suffers from other problems. Another solution would be to force the calls to the identifier members during the bootstrap of the application, but this one also has several drawbacks.
I'd like to know if there is so far an easy to implement though still elegant solution that is completely transparent to the developer to identify types over several executions, as the one above is for the single run of the application.
The problem of having unique persistent identifier for every class is unsolvable with C++. Sorry. You will either depend on the order of calling your initializaer functions, or, if you call them from initializers of static objects, on the order of static initializer (which will usually depend on the order of your object files in your link line).
And of course, there is no guarantee that hash will be unique.
You will have to use external script for this. In particular, something like this might be used:
// when class is first created
class Foo {
static int class_id = ?CLASS_ID?;
};
// after class is process by the script
class Foo {
static int class_id = 123; // Autogenerated by 'stamp_id.pl'
};
You might have a perl script running as part of the compilation (the very first thing) which opens all .h files in the project directory, reads all of them, counts all instances of Autogenerated by 'stamp_id.pl' and than stamps all ?CLASS_ID? with incremented counter (starting from the number of already generated ids). To add some safety, you might want a better pattern than simple ?...?, but I think, you got the idea.
Even if they are slightly different as questions, here I proposed a solution that maybe can fit well also with this question.
It isn't based on the CRTP idiom and it has the advantage of being a non-intrusive solution.
It follows a minimal, working example:
#include<cstddef>
#include<functional>
#include<iostream>
template<typename T>
struct wrapper {
using type = T;
constexpr wrapper(std::size_t N): N{N} {}
const std::size_t N;
};
template<typename... T>
struct identifier: wrapper<T>... {
template<std::size_t... I>
constexpr identifier(std::index_sequence<I...>): wrapper<T>{I}... {}
template<typename U>
constexpr std::size_t get() const { return wrapper<U>::N; }
};
template<typename... T>
constexpr identifier<T...> ID = identifier<T...>{std::make_index_sequence<sizeof...(T)>{}};
// ---
struct A {};
struct B {};
constexpr auto id = ID<A, B>;
int main() {
switch(id.get<B>()) {
case id.get<A>():
std::cout << "A" << std::endl;
break;
case id.get<B>():
std::cout << "B" << std::endl;
break;
}
}
The main problem is that the ids can change if an element is removed from the types list.
Anyway, it's trivial to define an empty placeholder to work around the issue.
Related
Changing values of classes/structs inside classes are a mystery to me. I tried to do some research today and came up with the following solution. I wonder if this is a proper way for a function to change stuff inside the class. Is there a need to for this to be somehow done with pointers? Is there a more proper way to accomplish this?
#include <iostream>
int main()
{
class Someclass {
private:
int Integer;
public:
Someclass(int i):
Integer(i){} //CTOR
struct Somestruct {
int a, b;
};
Somestruct Mystruct;
void func(){
Mystruct.a = Integer/2;
Mystruct.b = Integer*2;
};
};
Someclass A(10);
A.func();
std::cout << A.Mystruct.a << " " << A.Mystruct.b << std::endl;
}
The reason I am writing this code, is because I want to parse a file, starting from the line "Integer" into a customly defined struct "Mystruct" which this class should somehow deliver me. Is this an acceptable way to write such a code?
I understand that your question is about encapsulation, being understood that the inner struct is a data holder and the outer class has to manage it somehow.
Weaknesses of your design
In your design, Mystruct is public. So anything outside Someclass could access the data, but also change it. This is error prone, as there is no guarantee that the outside code doesn't break some invariant of the structure.
Ways for improvement
The cleanest thing would certainly to make some getters and setters to access the data. But with 30 members, it's a lot of code.
If your construction process initialises the struture's data, a second approach could be to limit outside access to read-only. You'd do that by making Mystruct private and offering a function returning a const reference:
class Someclass {
Somestruct Mystruct;
public:
...
const Somestruct& get() { return Mystruct; }
};
std::cout << A.get().a << " " << A.get().b << std::endl;
Online demo
Nevertheless before going into that direction, I'd check if access to the structure's raw data couldn't be encapsulated, for example by providing functions that manage the data without need to know the internals:
class Somestruct {
...
public:
ostream& show_simplified_specs(ostream& os) {
os << a << " " << b;
}
}
A third approach could be to use the builder design pattern to encapsulate the construction process of a Someclass based on Somestruct and other parts.
Pointers ?
Pointers should be avoided if possible. For example, suppose you have a vector of Someclass to keep all these classes in memory. At a moment in time, you get a pointer to an element's Mystruct. Suppose you'd then add a new item to the vector: all the previous pointers might get invalidated.
This same risk potentially exist with references. But I think that while it's a common idiom to cache a pointer returned by a function,in practice it's less common and appealing to copy a reference returned by a function.
Is this what you're looking for? I'm not much confident I understood you right.
template <int I>
struct Someclass;
template <>
struct Someclass<1>
{
int Integer = 1;
int a, b;
void func()
{
a = Integer/2;
b = Integer*2;
}
};
template <>
struct Someclass<2>
{
int Integer = 2;
int a, b, c;
void func()
{
a = Integer/2;
b = Integer*2;
c = Integer*Integer;
}
};
int main()
{
Someclass<1> A;
A.func();
std::cout << A.a << " " << A.b << std::endl;
Someclass<2> B;
B.func();
std::cout << B.a << " " << B.b << " " << B.c << std::endl;
return 0;
}
My solution I gonna use to add “C++ Extension Methods” to JNI jobjects to make NDK code more readable like (Uniform Function Call Syntax) is:
Subclass the class that I want to add extension methods.
For invoking the “Extension Methods” make a pointer of type ExtensionsClass to point to OriginalClass - (Although the pointed object is’nt an ExtensionsClass).
The overload is minimal & we can access public methods of the Original class.
#include <iostream>
// Represents a class external to my source
class Person {
public:
Person(){
privateage = 20;
}
int age() { return privateage; }
private:
int privateage;
short anotherField;
};
class PersonExtensions : private Person {
public:
inline int size() { return 5 + age(); }
//NoFieldsOnExtensionClass
};
int main() {
Person person;
PersonExtensions* pE = (PersonExtensions*) &person;
std::cout << pE -> size() << std::endl;
std::cout << (*pE).size() << std::endl;
std::cout << sizeof(Person) << std::endl;
std::cout << sizeof(PersonExtensions) << std::endl;
return 0;
}
Do you think that this incorrect pointer assignment, since “Extension Method” only accessed public members of extended class & extension class don’t going to have any Field variables, can represent a problem in the future?
The size of the object are the same.
Thanks a lot.
This is undefined behaviour.
Yes that can break at any point.
Consider overloading ->* or something instead.
Or just using a free function.
If you really want infix notation:
template<class T, class F>
struct extension_method_t {
F f;
friend auto operator->*( T& t, extension_method_t const& self ) {
return [&t,&self](auto&&...args)->decltype(auto) {
return self.f( t, decltype(args)(args)... );
};
}
};
template< class T, class F >
extension_method_t<T,F> extension_method( F f ) {
return {std::move(f)};
}
then:
auto size = extension_method<Person>([](auto& person)->int{
return 5+person.age();
});
Person p;
std::cout << (p->*size)() << "\n"; // prints p.age()+5
here we don't have an extension method, but we do have an extension method pointer.
What you are doing in your question code is Undefined Behavior, so an especially an optimizing compiler might do really "fun" things with it. In other words, don't do it, it might break at any time even if it works when you test it. Only way to make sure it would actually work would be to examine the produced assembly code after each compilation to make sure it does what you want, and this is essentially impossible, so it is never safe.
You are using private inheritance. So for same effect you can just do this:
class PersonExtensions {
public:
PersonExtensions(Person *person) : _person(person) {}
inline int size() { return 5 + _person->age(); }
private:
Person *_person;
};
If you instead used public inheritance (so you could just call Person methods through PersonExtensions), then you'd need to add a getter for _person (for cases where real Person is needed), and/or add delegates for Person methods (for so called static polymorphism).
This question already has an answer here:
Force explicit template instantiation with CRTP
(1 answer)
Closed 8 years ago.
So I read this article about using static initialization to register classes (http://quantumgraphics.blogspot.nl/2014/11/abusing-static-initialization.html). It's exactly what I need so I decided to implement it. I couldn't get it to work however, so I made a little test case to make sure I got the details right. Turns out even a simple example doesn't work (http://ideone.com/HDr8ZM):
#include <iostream>
int a = 0;
template<
class T
>
class Scriptable {
protected:
struct Proxy
{
Proxy() {
std::cout << "Proxy was executed! ID: " << T::id << std::endl;
a++;
}
};
static Proxy proxy_;
} ;
template<
class T
>
typename Scriptable<T>::Proxy Scriptable<T>::proxy_;
class Object : public Scriptable<Object> {
public:
constexpr static auto id = "[Object]";
} ;
int main() {
std::cout << "Done " << a << std::endl;
}
So basically what needs to happen (or more precisely, what I want to happen) is that the Proxy constructor should be executed before main. I want to use the the Proxy constructor to register the class with some singleton base class factory, but I don't think that's related to this code not working.
Can someone point me in the right direction? I'm probably missing a compiler flag or something (the example should compile with just the -std=c++11 flag). Or is there maybe a better way to do what I'm trying here?
Any help is greatly appreciated!
With Pradhan's link I was able to cook up what I needed:
#include <iostream>
int a = 0;
template <typename T, T /*unnamed*/>
struct nnb_ForceInit { };
template<
class T
>
class Scriptable {
public:
struct nnb_Proxy {
nnb_Proxy() {
std::cout << "Proxy was executed! ID: " << T::id << std::endl;
a++;
}
};
static nnb_Proxy __nnb_proxy__;
typedef nnb_ForceInit<nnb_Proxy&, __nnb_proxy__> __nnb_typedef_dummy__;
} ;
template<
class T
>
typename Scriptable<T>::nnb_Proxy Scriptable<T>::__nnb_proxy__;
class Object : public Scriptable<Object> {
public:
constexpr static auto id = "[Object]";
};
class Image : public Scriptable<Image> {
public:
constexpr static auto id = "[Image]";
};
class Error : public Scriptable<Error> {
public:
constexpr static auto id = "[Error]";
} ;
int main() {
std::cout << "Done " << a << std::endl;
}
I don't have a very clear idea how it works exactly but it seems to do what I want/works fine, so I guess that's it.
It doesn't work because there's no reason for your Proxy to ever get constructed. In this case, your main() doesn't even construct an Object - so why would the Proxy get constructed? You'd have to at least do that:
int main() {
Object o;
std::cout << "Done " << a << std::endl;
}
But then, simply constructing o doesn't reference the proxy in any way, so there's still no reason for it to be constructed. You'll have to touch it somehow. Simplest is to just reference it in Scriptable's constructor:
Scriptable() {
proxy_; // this line throws a warning, since this line does nothing,
// so replace it with something reasonable. but this line is
// enough to force proxy_ to be instantiated.
}
If I add those two bits (Object o; and the Scriptable constructor), then your code yields:
Proxy was executed! ID: [Object]
Done 1
Another way is to actually declare the proxy_ within the constructor:
Scriptable() {
static Proxy proxy_;
}
Compilers detect unused variable within the scope of a function. However, I found there are many variables, defined inside a structure, which are never read (but may have been written many times). Is there any tool/analyzer or even compiler flags to detect such unused variables?
Example:
For example, in the following structure:
typedef struct jj_t {
int count;
int *list;
} jj;
Analyzer may find that count is never read anywhere in the code.
My analyze of my code, shows this frequently happens! This was my fault, but it maybe the common case for the applications developed by different users over the years. Removing these variable may significantly reduces memory usage. I just need a tool for detecting such variables and I will manually remove them.
Thanks in advance.
I can give one solution.
But:
The effort is probably much bigger than checking by hand. Almost every good IDE for programmers allows you to see all references to a given variable.
This probably won't work in every case, you'll need to specialize for some types.
This will be collected by single program run.
The idea is to wrap your data types. With such encapsulation you can count every read operation.
See:
template <class T, class Parent, int NO=1>
class TReadDetector {
public:
struct Data {
bool touched;
Data () : touched(false) {}
~Data () {
if (!touched)
std::cerr << typeid(*this).name() << ": not read!!!\n" << std::endl;
}
};
static Data data;
TReadDetector () {}
TReadDetector (const T& t) : t(t) {}
operator T () const { data.touched = true; return t; }
TReadDetector& operator = (const T& t) { this->t = t; }
private:
T t;
};
template <class T, class Parent, int NO>
typename TReadDetector<T,Parent,NO>::Data
TReadDetector<T,Parent,NO>::data;
And usage:
Instead of:
struct A {
int a;
int b;
};
DO this:
struct A {
TReadDetector<int,A, 1> a;
TReadDetector<int,A, 2> b;
};
int main() {
A a;
a.a = 7;
a.b = 8;
std::cout << a.a << std::endl;
std::cout << TReadDetector<int,A, 1>::data.touched << std::endl;
std::cout << TReadDetector<int,A, 2>::data.touched << std::endl;
std::cout << "main() ended" << std::endl;
};
It will results in:
7
1
0
main() ended
N13TReadDetectorIi1ALi2EE4DataE: not read!!!
Notice last line printed after main(). You can collect this data to some external file.
Any analysis would have to be accross translation units.
In practice, unlike you, I've never found this to be a problem. About
the only solution I can think of off hand is to delete the members one by
one, and see if the entire application still compiles.
Removing the field from the structure can be dangerous in few cases if we have used the structure like,
typedef struct jj_t { int count; int *list; } jj;
jj *ptr = malloc (...);
//....
*ptr = 5; // NAIVE (but I have seen usage like this).
// Actually you are not modifying count, count was already deleted.
So, very hard to do the analysis you were asking for.
This is what I want to do:
enum MyEnum
{
ONE = 1, TWO, THREE
};
template<class T>
void func()
{
cout << T::TWO << endl;
}
int main()
{
func<MyEnum>();
};
It works, but I get a warning: "warning C4482: nonstandard extension used: enum 'MyEnum' used in qualified name"
How can I do this without getting the warning
Enum is a little tricky here. The type ONE and TWO will be in the outer namespace.
So adding the type to the name results in the warning.
You could just remove the qualifier
template<class T>
void func()
{
cout << TWO << endl;
}
Since the TWO is known in the outer namespace.
You could also just move your enum to some sort of enclosing struct.
struct EnumContainer
{
enum MyEnum
{
ONE = 1, TWO, THREE
};
};
template<class T>
void func()
{
std::cout << T::TWO << std::endl;
}
int main()
{
func<EnumContainer>();
};
Now the compiler should be fine.
Enums (pre C++0x) are treated like integral types.
In fact, the notation MyEnum::TWO is garbage: there is no class or namespace MyEnum. The names ONE, TWO, and THREE are brought into the namespace where the enum is defined [in this case, the global namespace].
You should get an error like TWO is not a member of MyEnum.
One way to emulate the behavior is to put it in a struct or class, like others have suggested.
While it would be nice to use the enum as the template parameter and have it recognize each individual enum separately as you've written it, it won't happen. Instead, may I suggest that you declare the following:
template<MyEnum T>
void func(){
std::cout << T << std::endl;
}
The great thing about C++ is that the way templates are structured gives you a Turning complete system. Hence, you don't need a separate call like this, as you've declared to get each individual enum value. You can create a separate function for each value when you need it and only when you need it.
Now, getting to the other problem of your question, as #delnan commented, you can't have two different Enums with the same name. You can, however, have a class with a member variable called TWO such that:
struct Foo{
int TWO;
};
struct Bar{
int TWO;
};
template<typename T>
void func(){
std::cout << T::TWO << std::endl;
}
Hope that helps.