Reputation: 2442
This prints nothing:
#include <iostream>
template <typename Derived>
struct A
{
static int test()
{
std::cout << "test" << std::endl;
return 0;
}
static inline int a = test();
};
struct B : public A<B>
{
};
int main(int argc, char** argv)
{
return EXIT_SUCCESS;
}
But this does:
#include <iostream>
template <typename Derived>
struct A
{
};
struct B : public A<B>
{
static int test()
{
std::cout << "test" << std::endl;
return 0;
}
static inline int a = test();
};
int main(int argc, char** argv)
{
return EXIT_SUCCESS;
}
And also this:
#include <iostream>
struct A
{
static int test()
{
std::cout << "test" << std::endl;
return 0;
}
static inline int a = test();
};
struct B : public A
{
};
int main(int argc, char** argv)
{
return EXIT_SUCCESS;
}
Not sure why or a workaround. I need the 'Derived' type to register it into a static table.
Upvotes: 0
Views: 109
Reputation: 2442
The (automatic) solution, as pointed here is to create a constructor that uses the registration variable. Also, the variable will be initialized only if an object is constructed.
#include <iostream>
template <typename Derived>
struct A
{
A()
{
a = 0;
}
static int test()
{
std::cout << "test" << std::endl;
return 0;
}
static inline int a = test();
};
struct B : public A<B>
{
};
int main(int argc, char** argv)
{
B b;
return EXIT_SUCCESS;
}
The 'a = 0' is to avoid a warning of unused variable. Overhead should be minimal.
Upvotes: 0
Reputation: 16434
The reason why the first snippet doesn't print anything is that the static variable is not instantiated. You have to use that variable in order to instantiate it.
The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or noexcept-specifiers of the class member functions, member classes, scoped member enumerations, static data members, member templates, and friends
As a workaround, you can just use that variable:
int main(int argc, char** argv)
{
(void) B::a;
return EXIT_SUCCESS;
}
Upvotes: 2
Reputation: 23711
Since A
is a template class, the static inline function/variable are not actually instantiated from the template unless they are used. Thus, you could do e.g. this:
#include <iostream>
template <typename Derived>
struct A
{
static int test()
{
std::cout << "test" << std::endl;
return 0;
}
static inline int a = test();
};
struct B : public A<B>
{
static inline int b = a;
};
int main(int argc, char** argv)
{
return 0;
}
Upvotes: 1