为什么编译器无法推断返回类型?
Why can't compiler deduce the return types?
如果返回类型恰好是模板参数,编译器不能推断函数的返回类型吗?或者我在遵循代码时犯了错误。
#include <iostream>
template <typename TT>
TT retBoolFail(bool a) {
return true;
}
template <typename TT>
void retBoolSuccess(bool a, TT& ret) {
ret = true;
return;
}
int main() {
bool ret;
retBoolSuccess(true, ret); // Success
retBoolFail(true); // Failure
return 0;
}
行"RetBoolFail(true)"失败,并出现以下错误。
-*- mode: compilation; default-directory: "~/work/c++/tupleTemplate/" -*-
Compilation started at Thu Mar 21 16:52:50
g++ -c simpletemp.cc -std=c++1z -g; g++ -o simpletemp simpletemp.o
simpletemp.cc: In function ‘int main()’:
simpletemp.cc:17:21: error: no matching function for call to ‘retBoolFail(bool)’
retBoolFail(true); // Failure
^
simpletemp.cc:4:4: note: candidate: template<class TT> TT retBoolFail(bool)
TT retBoolFail(bool a) {
^
simpletemp.cc:4:4: note: template argument deduction/substitution failed:
simpletemp.cc:17:21: note: couldn't deduce template parameter ‘TT’
retBoolFail(true); // Failure
^
Compilation finished at Thu Mar 21 16:52:50
谢谢。
不,扣除只发生在参数列表中。可以改用auto
,也可以仅将其设置为具有硬编码返回类型的非模板函数。
当模板名称用作要调用的函数时,模板参数推导仅使用函数参数和模板函数签名,而不使用函数体。
此规则在标准中难以更改的一个原因是,如果名称重载,则工作方式如何。 更全面的情况是:
-
名称查找查找一组函数和函数模板。
-
对于集合中的每个函数模板,模板参数由显式模板参数、推导和/或默认模板参数确定。 如果推导失败,或者如果将确定的模板参数替换为函数类型执行无效操作,则函数模板只是从重载集中丢弃为不可行。
-
对于每个函数签名(无论是否来自模板),都会进行检查以查看函数参数和函数参数是否匹配。否则,该功能不可行,将从重载集中丢弃。
-
重载分辨率比较其余可行函数。 对于大多数过程,模板中的函数类型被视为非模板函数,但有一些特定于函数模板专用化的最终决胜规则。
-
如果重载解析选择了函数模板专用化,并且上下文是需要存在函数定义的上下文,则还会实例化函数体以生成该定义。 如果将模板参数参数替换到函数体中执行无效操作,则程序格式不正确。
因此,此处区分函数模板的函数类型是否和实例化的时间,以及两种情况下模板参数使用无效的结果。 从功能体推断会混淆这一点。
但在其他一些情况下,函数模板返回类型中的模板参数可能涉及模板参数推导。 (此列表可能并不详尽。
如果从函数模板名称(或其指针大小写的地址)初始化指向函数的指针或对函数的引用,则返回类型将参与模板参数推导:
template <typename TT>
TT f();
unsigned int (&func_ptr)() = f; // TT deduced as unsigned int
int g(double (*)());
int g_of_f = g(f); // TT deduced as double
类或类模板可以具有转换函数模板。 然后,具有该类类型的表达式的某些用法可以隐式使用该模板,这需要在其返回类型中推导模板参数(这也是其声明中operator
关键字后面的内容)。
class A {
public:
template <typename TT>
operator std::shared_ptr<TT>() const;
};
std::shared_ptr<int> p = A{}; // TT deduced as int
另请注意,使用"占位符类型"作为其返回类型的函数或函数模板(返回类型包含关键字auto
)确实从主体的return
语句(由于"if constexpr
"而未跳过)推断其返回类型。 虽然没有模板头的函数仍然只是一个具有特定类型的函数,而不是函数模板,并且此推导是与任何模板参数推导分开的步骤。
auto retBool(bool a) {
return true; // return type is bool
}
template <typename T>
constexpr const auto* constify(T* ptr) {
return ptr; // return type is const T* (T* if T is already const)
}
类型推导不适用于仅返回类型的函数模板参数。
在您的情况下,您必须使用
retBoolFail<bool>(true);
您必须提示编译器才能推断返回类型的类型。即使在函数模板中使用auto
,仍需要在调用站点提示编译器。
- 在模板化成员函数的返回类型中使用 std::enable_if 时的编译器差异
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 为什么编译器不能从返回类型中推断出模板参数?
- 编译器无法推断返回类型?
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 为什么编译器无法推断返回类型?
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- typedef映射作为返回类型到函数会引发编译器错误
- 为什么编译器需要在已经类限定的成员函数定义的返回类型上使用类限定符
- 当我使用模板时,编译器无法将函数的返回类型从 double 转换为 int
- 函数声明和定义的返回类型不匹配,编译器可以吗?
- 编译器的函数返回类型验证
- C++ typedef 和返回类型:如何让编译器识别使用 typedef 创建的返回类型
- g++编译器忽略const返回类型
- 模板类中的尾随返回类型(GNU和Microsoft编译器之间的矛盾)
- 如何让编译器推断模板的返回类型
- 编译器警告:无法推导lambda返回类型
- 函数映射容器中C++函数返回类型重载:自动推导失败,并出现编译器错误
- 为什么编译器不显示这些返回类型的错误?
- 如何让编译器推断出c++ 11中模板化方法的返回类型