So I got a class that specifies a constant with a special meaning for each type.
I use something like this
template<class Type>
class SpecialKeyProvider
{
static const Type SPECIAL_KEY;
}
with one or more specializations for Types that will also be used but are not numeric.
So I initialize the static member outside the class’ definition like I have to:
// This seems to have to be in a cpp as having it in the same header,
// will result in duplicate definitions of SPECIAL_KEY;
// This particular instantiation is kind of problematic anyways, see
// the end of my question for another question on this one.
template<>
string SpecialKeyProvider<string>::SPECIAL_KEY = "__SPECIAL";
template <class Type>
Type SpecialKeyProvider<Type> = std::numeric_limits<Type>::max();
Unfortunately the SpecialKeyProvider is used in a very central Container class. This container has lots of methods that should be inlined for performance reasons and is used in numerous places. So I put the whole container in the header file. But now that the SpecialKeyProvider is used, I still have to link SpecialKeyProvider.o to pretty much every single binary in my project.
Is there any way to get rid of that and to do the template specialization in the header without getting an error due to “multiple definitions”?
Second question concerning the string constant.
// I know this is bad code but I don't know how to do it better.
template<>
string SpecialKeyProvider<string>::SPECIAL_KEY = "__SPECIAL";
I know (and the linter reminds me), that using constants of any class type is generally a bad idea due to indeterminant order of construction (google style guide), in particular strings. While I can normally use a const char[] instead, I don’t know what to do in this case, since I want the template to be instantiated for strings. Using the template (i.e. using my container class that used the SpecialKeyProvider) with char* instead would be incredibly painful.
I’m really thankful for any advice.
Put the
classwithstatic constin an unnamed namespace in your header file:This will not cause any linker error even if you declare variables in a header file; Because for every
.cppfile a different unnamednamespaceis created. For your case you have onlyconstvariables declared, so there is an assurity that all the .cpp files are reading the same value.Edit: Regarding your second question, I don’t know what could be the problem with the above approach as for every translation unit a different
constcopy will be created. See if the lint still complains.