static initialization of Template classes for singleton object - c++

We have a singleton template class as defines below
template<class T> class Singleton{
T& reference(){
return objT;
}
private:
T objT;
};
And another user defined class which uses this singleton
class TestClass{
static Singleton<TestClass> instance;
static TestClass * getPointer()
{
return &instance.objT;
}
private:
TestClass(){}
};
template<TestClass>
Singleton<TestClass> TestClass::instance;
On compilation with GCC we are getting the error
In function static_initialization_and_destruction undefined reference to Singleton::Singleton().
What can be the reason for this.

Ignoring the fact, that in your example there is no need for Singleton template, consider this simplified example (I am using structs to avoid access issues):
template <class T>
struct Singleton
{
T object;
};
struct TestClass;
typedef Singleton<TestClass> TCS;
TCS test1; // not ok, no definition of TestClass available;
struct TestClass
{
TestClass(){}
static TCS test2; // not ok, no definition of TestClass available;
};
TCS test3; // ok, TestClass is defined;
To declare a member of type T, you need a complete definition of this type T. So, test1 and test2 are not legal - there is only a declaration, not definition of T. On the contrary, test3 is legal - it is located after the complete definition of the class. Easiest fix here is to use pointer to type - to declare a pointer to type T, you need a declaration instead of definition for the type T:
template <class T>
struct Singleton
{
T * object;
};

static Singleton<TestClass> instance;
you are actually trying to create an instance of class Singleton in above line; which will look for default constructor Singleton() (which is already present as you haven't explicitly defined it private).
T& reference() is a private method in your class.
And I didn't really understand this
template<TestClass>
Singleton<TestClass> TestClass::instance;
Are you sure what you are trying to do? Cause am not ;)
Maybe you want to read this to understand what you are doing http://www.yolinux.com/TUTORIALS/C++Singleton.html

Easiest fix: Don't use a singleton.

Related

Why would one wrap a struct in an anonymous union? (STL msvc implementation)

The STL <memory> header (MSVC implementation) contains a class called:
template <class _Ty> class _Ref_count_obj2 : public _Ref_count_base
This class has a member:
union {
_Wrap<_Ty> _Storage;
};
where _Wrap is defined as:
template <class _Ty>
struct _Wrap {
_Ty _Value; // workaround for "T^ is not allowed in a union"
};
From my understanding, this code is designed to hold an object of type _Ty following its construction via the new operator. However I can't figure out why this was done; it seems like using a struct instead of a struct inside a union would work just as well.
Can anyone explain the reasoning behind this? Also, can anyone explain the comment in the _Wrap definition?
First, embedding the _Storage member in a union will prevent default destruction of that object (which is, more than likely, a non-trivial type); this appears to be essential, as the class involved is a reference counter. (By default, unions have a deleted destructor; see, for example: Is a Union Member's Destructor Called .)
Second, using an anonymous union 'moves' the _Storage identifier into the enclosing scope, thus removing any need for X.-style notation (if the union were to be named X). From cppreference:
Members of an anonymous union are injected in the enclosing scope (and
must not conflict with other names declared there).
Last, the need to wrap the union's member into a templated structure is so that the class will work with reference types, which are not allowed in unions. To check this last part out, try the following code with the commented-out lines made active:
template <class _Ty>
struct _Wrap {
_Ty _Value; // workaround for "T^ is not allowed in a union"
};
template<class T>
class bob {
public:
bob(T t) : uncle{t}//, aunty(t)
{
}
private:
union {
_Wrap<T> uncle;
};
// union {
// T aunty;
// };
};
int main()
{
int i = 42;
bob<int&> b{ i }; // Note: Template uses a REFERENCE type
return 0;
}

Inheriting from a template class using the inheriting class

When I inherit from a class the compiler has to know the definition of the base class in order to create it. But when I inherit from a template class using oneself (the inheriting class), how can the compiler create the code? It does not know the size of the class yet.
#include <iostream>
template <class T> class IFoo
{
public:
virtual T addX(T foo, double val) = 0;
// T memberVar; // uncomment for error
};
class Foo : public IFoo<Foo>
{
public:
Foo(double value)
: m_value(value) {}
Foo addX(Foo foo, double b) override
{
return Foo(foo.m_value + b);
}
double m_value;
};
int main()
{
Foo foo1(1);
Foo foo2 = foo1.addX(foo1, 1);
std::cout << foo2.m_value;
}
First I thought it works because it's an interface but it also works with a regular class.
When I store the template as a member i get an error that Foo is undefined, just as I expected.
The general concept here is called the Curiously Recurring Template Pattern or CRTP. Searching on that will get lots of hits. see: https://stackoverflow.com/questions/tagged/crtp .
However there is a simple explanation that likely answers your question without getting too much into CRTP. The following is allowed in C and C++:
struct foo {
struct foo *next;
...
};
or with two types:
struct foo;
struct bar;
struct foo {
struct bar *first;
...
};
struct bar {
struct foo *second;
...
};
So long as only a pointer to a struct or class is used, a complete definition of the type doesn't have to be available. One can layer templates on top of this in a wide variety of ways and one must be clear to reason separately about the type parameterizing the template and its use within the template. Adding in SFINAE (Substitution Failure Is Not An Error), one can even make templates that do no get instantiated because things cannot be done with a given type.
With this definition of template class IFoo, the compiler does not need to know the size of Foo to lay out IFoo<Foo>.
Foo will be an incomplete class in this context (not "undefined" or "undeclared") and usable in ways that any incomplete type can be used. Appearing in a member function parameter list is fine. Declaring a member variable as Foo* is fine. Declaring a member variable as Foo is forbidden (complete type required).
how can the compiler create the code?
Answering this question would be the same as answering this question: How can the compiler compile that?
struct Type;
Type func(Type);
Live example
How can you define a type that doesn't exist and yet declare a function that use that type?
The answer is simple: There is no code to compile with that actually use that non-existing type. Since there is no code to compile, how can it even fail?
Now maybe you're wondering what is has to do with your code? How does it make that a class can send itself as template parameter to it's parent?
Let's analyze what the compiler see when you're doing that:
struct Foo : IFoo<Foo> { /* ... */ };
First, the compile sees this:
struct Foo ...
The compiler now knows that Foo exists, yet it's an incomplete type.
Now, he sees that:
... : IFoo<Foo> ...
It knows what IFoo is, and it knows that Foo is a type. The compiler now only have to instanciate IFoo with that type:
template <class T> struct IFoo
{
virtual T addX(T foo, double val) = 0;
};
So really, it declares a class, with the declaration of a function in it. You saw above that declaring a function with an incomplete type works. The same happens here. At that point, Your code is possible as this code is:
struct Foo;
template struct IFoo<Foo>; // instanciate IFoo with Foo
So really there's no sorcery there.
Now let's have a more convincing example. What about that?
template<typename T>
struct IFoo {
void stuff(T f) {
f.something();
}
};
struct Foo : IFoo<Foo> {
void something() {}
};
How can the compiler call something on an incomplete type?
The thing is: it don't. Foo is complete when we use something. This is because template function are instantiated only when they are used.
Remember we can separate functions definition even with template?
template<typename T>
struct IFoo {
void stuff(T f);
};
template<typename T>
void IFoo<T>::stuff(T f) {
f.something();
}
struct Foo : IFoo<Foo> {
void something() {}
};
Great! Does it start looking exactly the same as your example with the pure virtual function? Let's make another valid transformation:
template<typename T>
struct IFoo {
void stuff(T f);
};
struct Foo : IFoo<Foo> {
void something() {}
};
// Later...
template<typename T>
void IFoo<T>::stuff(T f) {
f.something();
}
Done! We defined the function later, after Foo is complete. And this is exaclty what happens: The compiler will instanciate IFoo<Foo>::stuff only when used. And the point where it's used, Foo is complete. No magic there either.
Why can't you declare a T member variable inside IFoo then?
Simple, for the same reason why this code won't compile:
struct Bar;
Bar myBar;
It doesn't make sense declaring a variable of an incomplete type.

C++ static variables of unreferenced class

In the following program "Here" is printed:
#include <iostream>
class Base
{
static bool temp;
static bool initTemp()
{std::cout<<"Here\n";return true;}
};
bool Base::temp = Base::initTemp();
class Derived : public Base
{};
int main() {int a;std::cin>>a;}
In the following program "Here" is not printed:
#include <iostream>
template <class T>
class Base
{
static bool temp;
static bool initTemp()
{std::cout<<"Here\n";return true;}
};
template <class T>
bool Base<T>::temp = Base<T>::initTemp();
class Derived : public Base<int>
{};
int main() {int a;std::cin>>a;}
In both cases Base is never referenced. The only difference is that in the second case it is a template class. Can anyone explain to me why this behavior occurs. I am using VS 2012.
In both cases Base is never referenced.
And that is precisely the reason why you see nothing being printed to the standard output.
The definition of a class template's static data member does not get instantiated unless you use that data member; like member functions, the definitions of static data members of a class template are instantiated on demand.
This is specified in paragraph 14.7.1/1 of the C++11 Standard:
[...] The implicit instantiation of a class template specialization causes the implicit
instantiation of the declarations, but not of the definitions or default arguments, of the class member functions,
member classes, scoped member enumerations, static data members and member templates. [...]
Since your client code never refers to Base<>::temp, there is no need to construct and initialize it.
As a side note, this signature:
void main()
Is not valid (standard) C++. If you want to write portable code, the return type of main() should always be int.
In the first case, you don't instantiate Base, but you do call the static function:
bool Base::temp = Base::initTemp();
In the second case, you never instantiate the template:
template <class T>
bool Base<T>::temp = Base<T>::initTemp();
You can explicitly instantiate the Base class template, as with:
template class Base<int>;
And then you will see "Here" printed.
You cannot create variable of undefined class, which you seem to do with line:
template <class T>
bool Base<T>::temp = Base<T>::initTemp();
You cannot allocate variable of undefined type. What you need is write something like:
Base<int>::temp = value;
of cause there will be different variable allocated for each type provided, so you cannot have common static variable for a template class. You'll have separate variable for each type you instantiate your template instead.
To downvoters here is complete example:
#include <iostream>
template<class T>
class X
{
public:
static int v;
};
template<class T>
int X<T>::v = 0;
int main()
{
X<int>::v = 3;
X<char>::v = 2;
using namespace std;
cout << X<char>::v << endl << X<int>::v;
}
It prints 2 3 which means you cannot have single variable for all classes you'll instantiate your template.

How to have static data members in a header-only library?

What is the best way to have a static member in a non-templated library class,
without placing the burden of defining the member on the class user?
Say I want to provide this class:
class i_want_a_static_member
{
static expensive_resource static_resource_;
public:
void foo()
{
static_resource_.bar();
}
};
Then the user of the class must not forget to define the static member somewhere
(as already answered many times):
// this must be done somewhere in a translation unit
expensive_resource i_want_a_static_member::static_resource_;
I do have an answer below, but it has some disadvantages. Are there better and/or more elegant solutions?
C++17 and above
Use inline static variables for non-dynamic initialization:
struct Foo
{
inline static int I = 0;
};
And use function local static variables otherwise:
struct Foo
{
static std::string& Bar()
{
static std::string S = compute();
return S;
}
};
C++14 and below
Use function local statics, as they are plain easier to use.
If for some reason you really wish for a static data member, then you can use the template trick:
template <typename T = void>
struct Foo
{
static int I = 0; // inline initialization only for simple types.
};
template <typename T>
int Foo<T>::I;
On local statics
For resources which require dynamic initialization, it is best to use a local static.
The order in which file-scope or class-scope statics are dynamically initialized is undefined, in general, leading to the Static Initialization Order Fiasco when you try to read a uninitialized static as part of the initialization of another. Local static solve the issue by being initialized lazily, on first use.
There is some slight overhead to using local statics, however. From C++11 onwards, the initialization is required to be thread-safe, which typically means that any access is gated by an atomic read and well-predicted branch.
My own solution is to use a templated holder class, as static members work fine in templates, and use this holder as a base class.
template <typename T>
struct static_holder
{
static T static_resource_;
};
template <typename T>
T static_holder<T>::static_resource_;
Now use the holder class:
class expensive_resource { /*...*/ };
class i_want_a_static_member : private static_holder<expensive_resource>
{
public:
void foo()
{
static_resource_.bar();
}
};
But as the name of the member is specified in the holder class, you can't use the same holder for more than one static member.
As of C++ 17. You can now use inline variables to do this:
static const inline float foo = 1.25f;

how to implement Singleton in C++

This post is what I just read.
The way he implements Singleton in C++ confuses me. I got several Questions about it and here is his code:
template<typename T>
class Singleton {
public:
static T& getInstance() { //Question 1
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};
Question
I think we should put the static T& getInstance()'s definition outside of the class body, right?
He tries to make class DebugLog a singleton class, but when he inherits Singleton<DebugLog>, the DebugLog doesn't already exist, right? If right, then how can the template class Singleton instantiate an un-existent class?
1) Nope, it doesn't matter how you structure your code. Singleton isn't a class, by the way: It's a template. Since the full template definition must be visitible at any instantiation site anyway, you might as well define everything inline.
2) class DebugLog : public Singleton<DebugLog> is fine. We are not inheriting from a non-existing class; rather, we are inheriting from the class Singleton<DebugLog>. Templates can be instantiated on incomplete types. (There are several rules what you can and cannot do with such a type parameter.)
For example, template <typename T> class Foo { }; can certainly be instantiated on any type without problem. More interestingly, template <typename T> struct PointerFactory { typedef T * type; }; can be instantiated on any type, complete or not. In the present situation, the purpose of the template parameter in the CRTP is solely to inform the base class of its eventual derived type, so this is entirely fine.
It would certainly be cleaner if the function were defined outside of
the class, and make the code easier to read and to maintain. In this
case, however, the complete class is small enough that the difference
isn't very great, and of course, because we're dealing with a template,
the actual definition still has to be included in every translation unit
which uses it.
The C++ standard doesn't speak of “existence” with regards to classes (or anything
else). At the point of template instantiation, name lookup finds
DebugLog, and finds that it is a class (thus, a type). At that point,
it is an incomplete type, and there are only limited things you can do
with an incomplete type. If the class template which is instantiated
doesn't do anything that requires a complete type (and Singleton
doesn't), then there is no problem. (Note that only the class
definition is instantiated at this point; class member functions will
not be instantiated until they are used.)
I might add that there is still one important thing missing from the
code you posted: there is no definition for the declaration
Singleton::instance. You still need to add a:
template<typename T> T Singleton<T>::instance;
somewhere.
You must use a pointer to T in this case:
template<typename T>
class Singleton {
public:
static T& getInstance() {
static T * instance = NULL;
if (!instance)
instance = new T;
return *instance;
}
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};