c++ - 返回类型为 T 的函数模板无法编译

标签 c++ templates gcc function-templates

下面的代码可以正常编译:

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

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

ideone编译成功:http://ideone.com/dR6iZ

但是当我提到返回类型时,它无法编译:

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

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

现在它给出错误:

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

ideone 的代码:http://ideone.com/b9aSb

即使我将返回类型设置为const T,它也是doesn't compile .

我的问题是:

  • 为什么不编译?
  • 返回类型与错误和函数模板实例化有什么关系?

最佳答案

您不能从函数返回数组,因此模板实例化失败,并且没有匹配的函数。

由于 SFINAE,您会收到此特定错误- 编译器无法实例化您的函数并不是真正的错误,没有匹配函数的错误。

可以返回对数组的引用 - 返回 T const & 将起作用。

编辑:回应评论:

首先,这实际上是 SFINAE 的一个不错的例子。

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

当编译器编译它时,它会首先尝试实例化模板化的 f,为 const char [3] 类型创建一个完全匹配。由于上述原因,这失败了。然后它会选择不完全匹配的普通函数,并在调用中将 const char [3] 衰减为 const char *

关于c++ - 返回类型为 T 的函数模板无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5306755/

相关文章:

c++ - 从 64 位转换为 32 位时,Gcc 不会给出任何警告

gcc - Linux 是否有与 Windows "resource files"等效的代码?

c++ - 为什么 Clang 和 VS2013 接受移动大括号初始化的默认参数,但不接受 GCC 4.8 或 4.9?

c++ - std::move(T&&) 和临时对象。临时从哪里来?

c++ - 在 C++ 中用给定的字母打印三角形

Django 模板过滤器 : counting objects

c++:带模板的函数指针

c++ - 程序在删除结构中的指针数组时崩溃

c++ - 从 C++ 中的其他文件访问函数时遇到问题

c++ - 为什么模板参数替换的顺序很重要?