I am attempting to program a string concatenation function which utilizes my 3D library's string conversion functions, implemented with a variadic template.
The library's conversion function behaves unusually if a string (either const char[] literal or std::string) is passed to it. as it does not actually possess functions for those types, so I want to specialize the template to pull those out and not run them through the converter. Optimization would be a good reason even if the converter handled them.
template<typename T>
inline String c(T a)
{
return Ogre::StringConverter::toString( a );
}
template<>
inline String c(String s)
{
return s;
}
template<>
inline String c(const char s[])
{
return s;
}
template<typename T, typename... Args>
inline String c(T a, Args... args)
{
return Ogre::StringConverter::toString( a ) + c(args...);
}
template<typename... Args>
inline String c(String s, Args... args)
{
return s + c(args...);
}
template<typename... Args>
inline String c( const char s[], Args... args)
{
return s + c(args...);
}
However, when I compile my program, string literals sometimes fall through the const char[] specialization and are handled by the base, unspecialized template. The command:
U::c( "This is dMap[500][500]: ", dMap[500][500], " and this is 5: ", 5, "." )
returns
This is dMap[500][500]: 112true5.
"true" being what toString returns if a string literal is passed to it. Debugging confirms that the second string literal is caught by the generic String c(T a, Args... args)
, but not the first or third, which are handled by the specialization.
This seems related to the problem mentioned in Selecting string literal type for template specialization, but changing my template parameter declaration match those suggested in that solution, inline String c( const char (&s) [N], Args... args )
, cause the first parameter to be caught by the specialized template, but not the second or third. Something unusual is happening here and I cannot figure out what it is.