mercredi 1 avril 2015

Template specialization with constexpr non POD data initialization results in linker error when used in constructor as default value

Consider this:



struct TestStruct
{
uint16_t m_a : 8;
uint16_t m_b : 8;
};

template<typename T>
struct some_trait
{
constexpr static const TestStruct value = {0,0};
};

template<>
struct some_trait<int>
{
constexpr static const TestStruct value = {1,1};
};

template<class T>
class Obj
{
public:
Obj(TestStruct t = some_trait<T>::value) : m_t(t)
{

}

TestStruct m_t;
};

int main(int argc, const char * argv[])
{
// Linker error here -> Undefined symbol for some_trait<int>::value
Obj<int> o;

TestStruct t = some_trait<int>::value;
Obj<int> o1(t); // -> This works
}


The following produces a linker error, complaining that the some_trait is not defined. I have two questions:




  1. Why is this happening? I'm guessing it has to do with either the constexpr specifier or the non-POD type of TestStruct ?




  2. Is there a way to make it work, while still keeping the default value in the constructor?




Thanks!


Aucun commentaire:

Enregistrer un commentaire