Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function template with return type T doesn't compile

The following code compiles fine:

template<typename T>
void f(const T &item) { return; }

int main() 
{
  f("const string literal");
}

Compilation succeeded at ideone : http://ideone.com/dR6iZ

But when I mention the return type, it doesn't compile:

template<typename T>
T f(const T &item) { return item; }

int main() 
{
  f("const string literal");
}

Now it gives error:

prog.cpp:6: error: no matching function for call to ‘f(const char [21])’

Code at ideone : http://ideone.com/b9aSb

Even if I make the return type const T, it doesn't compile.

My question is :

  • Why does it not compile?
  • What does the return type has to do with the error and the function template instantiation?
like image 258
Nawaz Avatar asked Mar 15 '11 02:03

Nawaz


People also ask

Are templates resolved at compile-time?

All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!

What does template <> mean in C++?

It's a specialization. template<> means that the specialization itself is not templated- i.e., it is an explicit specialization, not a partial specialization.

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

How templates are compiled?

Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository.


1 Answers

You cannot return an array from a function, so template instantiation fails, and there's no matching function.

You get this particular error because of SFINAE - It's not really an error that the compiler cannot instantiate your function, it is an error that there's no matching function.

You can return a reference to an array - returning T const & will work.

EDIT: In response to comments:

First, this is actually a decent example of SFINAE.

template<typename T> T f(const T &item) { return item; }
char const * f(void const * item) { return 0; }
int main() {
  f("abc");
}

When the compiler compiles this, it'll first try to instantiate the templated f, to create an exact match for the type const char [3]. This fails, because of the mentioned reasons. It'll then select the inexact match, the plain function, and in the call decay the const char [3] to a const char *.

like image 72
Erik Avatar answered Oct 05 '22 20:10

Erik