Question

I'm having difficulty getting the correct syntax for a template specialisation which accepts a regular c-style string. For example

namespace RubyUtils
{
    template<class T> VALUE toValue(const T& v);
};

template<> VALUE toValue(char const* & v)
{
    return toValue<string>(v);
}

and then at the call site

return RubyUtils::toValue("Life the universe and everything");

gives an error

unresolved external symbol "unsigned long __cdecl RubyUtils::toValue<char const [33]>(char const (&)[33])" 

how should I structure the specialisation to enable passing in c-style strings?

UPDATE: Fixed the template specialisation to have correct syntax template => template<>

Was it helpful?

Solution

I think that the problem you're encountering is probably related to the fact that you've defined two templates - one inside of the namespace, and one out. The error is likely due to this confusion.

But more importantly, as a general rule, you do not want to specialize function templates. Template specialization for function has lots of funky rules associated with it that almost universally result in the wrong thing getting called. Rather, just use regular function overloading:

namespace RubyUtils
{
    template<class T> VALUE toValue(const T& v);
    VALUE toValue(char const* v)
    {
        return toValue<string>(v);
    }
};

The way function overloading works, calling the toValue function with a C-style string will cause the non-template toValue to get selected ahead of the toValue template, essentially doing the specialization for you. More generally, with function templates, prefer using overloading to specialization. It's just safer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top