Tom
Tom

Reputation: 8012

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?

Upvotes: 0

Views: 233

Answers (1)

Barry
Barry

Reputation: 303890

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.

Upvotes: 4

Related Questions