Reputation: 323
I have a templated struct to store a static char*
array, like this:
template<typename T>
struct EnumStrings {
static const char* const data[];
};
And I would like to specialize it this way:
template<> const char* const EnumStrings<SomeType>::data[] =
{"item1", "item2", "item3", "item4"};
If I place this instantiation in a header file, and this header file is included in multiple units, I get this linker error:
multiple definition of `EnumStrings<SomeType>::data'
Now, if I place this instantiation in the cpp file, other code using the data
array cannot deduce its size with the sizeof
operator, leading to the following error:
error: invalid application of ‘sizeof’ to incomplete type ‘const char* const []’
Because I need to be able to iterate over this array, so, I am stuck... Any suggestion? Of course, I would like not to have to specify the size of the array somewhere, but maybe that's the only possibility.
Upvotes: 1
Views: 422
Reputation: 2279
You can put the struct declaration and definition of the data array specialization in an anonymous namespace. Struct will then have internal linkage which should prevent multiple definition errors.
namespace {
template<typename T>
struct EnumStrings {
static const char* const data[];
};
template<> const char* const EnumStrings<int>::data[] =
{"item1", "item2", "item3", "item4"};
}
Upvotes: 0
Reputation: 7473
You should divide declaration and definition of data
array specialization. Put this in your header file:
template<typename T>
struct EnumStrings {
static const char* const data[];
};
// declaration of `data` array specialization
template<> const char* const EnumStrings<SomeType>::data[4];
And this in your cpp
file:
// definition of `data` array specialization
template<> const char* const EnumStrings<SomeType>::data[] =
{"item1", "item2", "item3", "item4"};
Upvotes: 1
Reputation: 217275
in C++11 following works:
// In header:
class SomeType;
template<typename T> struct EnumStrings;
template<>
struct EnumStrings<SomeType> {
static constexpr
const char* const data[] =
{"item1", "item2", "item3", "item4"};
};
// in cpp, if address of data is taken.
constexpr
const char* const EnumStrings<SomeType>::data[];
Upvotes: 1