Tom Tom - 3 months ago 21
C++ Question

Pass-by-reference template functions with `const char *` specialisation

I have a template function:

template<typename T>
void foo(T const & t);


And some specialisations of that function:

template<> void foo<int>(int const & t) {
cout << t << endl;
}

template<> void foo<const char *>(const char * const & t) {
cout << t << endl;
}


And some ways I want to call that function:

foo(3);
foo("Hello, world.");


But I can't figure out how to formulate the template so that template type deduction gets literals of both
int
and
const char *
right. If I do the above, then I get
undefined reference to void foo<char [14]>(char const [14] &)
. I tried recasting the template like this:

template<typename T>
void foo(T t);

template<> void foo<int>(int t) { ... }
template<> void foo<const char *>(const char * t) { ... }


which works, but of course now I get call-by-value semantics, requiring any class types that I use as the template parameter to have a copy constructor.

Is there no way to write a pass-by-reference template function with a
const char *
specialisation that works?

Answer

This:

foo("Hello, world.");

Doesn't call foo<const char*>. It calls foo<char[14]>, since foo takes a T const&. Your specialization isn't called since it isn't the same type as the template.

That said, just don't specialize. Overload:

template<typename T>
void foo(T const& );

void foo(int const& );

void foo(char const* );

It's way easier to reason about and is more likely to do what you actually want.

Comments