为什么函数返回类型中不允许参数推导?
Why isn't argument deduction allowed in function return type?
最明显的答案可能是 -因为标准是这样说的。
这很好,但我正在思考它以了解这种选择背后的原因。
请考虑以下示例:
template<typename T>
struct S { S(T) {} };
S f() { return 0; }
int main() {
auto s = f();
(void)s;
}
它无法编译并出现以下错误:
错误:使用类模板"S"需要模板参数;函数返回类型中不允许参数推导
很容易修复,这不是问题,这样的东西就可以了:
auto f() { return S{0}; }
但是,我想了解在函数返回类型中也允许类模板参数推导的缺点是什么。
乍一看,它看起来像一个愚蠢的限制,但我很确定我在这里错过了一些重要的东西。
这里没有任何语言法:如果指定返回类型(而不是auto
或T
,其中T
是模板类型(,则该返回类型必须有效。 让我给你一个更简单、更好的例子:
std::vector function() {
return std::vector<int>();
}
显然,即使没有花哨的模板,它也无法编译auto
和类型推导,因为std::vector
不是一个类型,std::vector<int>
是。
当您将S
指定为返回类型时,您基本上
- 阻止编译器推导类型本身
- 指定无效的返回类型,因为
S
不是类型,S<int>
是。
为什么函数返回类型中不允许参数推导?
因为标准是这么说的。
你可以问这样一个问题:为什么这些代码行之间存在差异:
S s = 0; // OK
S s() { return 0; } // error - even though this is also copy-initializing an "S" from 0
你可以想出一个挥手的解释,为什么第一个应该没问题,为什么第二个不应该 - 但从根本上说,类模板参数推导被提出来只解决第一种情况,而不是第二种情况。第一个是可以的,因为标准是这样说的,第二个是错误的,因为标准是这样说的。
提出了一个扩展(P1021,在"函数的返回类型推断"下(,以解决第二种情况。不管你是否认为这是一个好主意... ̄\_(ツ)_/̄
只是我挥手的两分钱,总结了我的理解:
在
S f() { return 0; }
S
不是可以推断的类型,它只是一个模板。你可以写
template<typename T>
S<T> f() { return 0;}
但现在很明显,对于一个电话
auto s = f();
没有办法推断T
应该是什么类型。
相关文章:
- 不允许运算符 const 参数调用 const 成员函数
- 为什么C++不允许两个同名的函数/类模板,区别仅在于非类型模板参数(整型)的类型?
- antlr cpp target 的标头部分不允许使用具有默认参数的外部函数
- 为什么我们不允许将纯引用参数传递给 std::thread,但允许传递原始指针?
- 为什么不允许自动作为函数参数?
- 为什么函数返回类型中不允许参数推导?
- 网站组装 |错误:'C/ObjC'不允许使用无效'-std=c++11'参数
- 如何编写模板重载函数,并在模板参数不允许实例化某个类时触发回退
- C++ 不允许将'this'用作非类型模板参数
- 是否不允许编译器假设 const-ref 参数将保持 const?
- 为什么在lambda参数中不允许自动
- 为什么C++不允许参数成为默认参数
- 在 QGraphicsScene 中拖动 QPixmap:如何避免 lambda 参数中不允许'auto'
- 传递动态大小的数组(不允许使用参数)
- 不允许非类型参数的部分模板专用化
- 为什么C 不允许在非模板函数中进行变异参数
- 为什么不允许我提供函数参数
- 整型常量表达式中不允许使用模板参数
- 为什么模板模板参数不允许在参数列表后使用"typename"
- 为什么默认参数不允许出现在非默认参数之前