Joh*_*itb 12 c++ overloading rationale auto c++14
为什么以下两个模板不兼容且无法重载?
#include <vector>
template<typename T>
auto f(T t) { return t.size(); }
template<typename T>
auto f(T t) { return t.foobar(); }
int main() {
f(std::vector<int>());
}
Run Code Online (Sandbox Code Playgroud)
我认为它们(或多或少)等效于以下编译精细(因为我们做不到,decltype auto(t.size())我不能给出一个没有一些噪音的精确等价物......).
template<typename T>
auto f(T t) -> decltype(t.size() /* plus some decay */) { return t.size(); }
template<typename T>
auto f(T t) -> decltype(t.foobar() /* plus some decay */) { return t.foobar(); }
Run Code Online (Sandbox Code Playgroud)
main.cpp:6:16: error: redefinition of 'f'然而,Clang和GCC抱怨我是否放弃了尾随返回类型.
(请注意,这是一个rationale问题.我不是在标准中寻找定义此行为的地方 - 如果您愿意,您也可以在答案中包含这个地方 - 但是要解释为什么这种行为是可取的或现状).
该推断返回类型显然不能是签名的一部分.但是,从return语句中推断出确定返回类型(并参与SFINAE)的表达式存在一些问题.假设我们采用第一个return语句的表达式并将其粘贴到一些调整后的虚拟尾部返回类型中:
如果返回的表达式依赖于本地声明怎么办?这不一定会阻止我们,但它会极大地扼杀规则.不要忘记我们不能使用声明的实体的名称; 这可能会使我们的尾随返回型天高可能复杂化,可能完全没有任何好处.
此功能的一个常见用例是返回lambdas的函数模板.然而,我们很难做出签名的一部分 - 之前已经详细阐述了可能出现的复杂情况.单独管理就需要英勇的努力.因此,我们必须使用lambdas排除函数模板.
如果声明的签名也不是定义,则无法确定声明的签名,引入一整套其他问题.最简单的解决方案是完全禁止(非定义)此类函数模板的声明,这几乎是荒谬的.
幸运的是,N3386的作者努力保持规则(和实现!)简单.我无法想象如何在一些极端情况下不必自己写一个尾随返回类型,这需要一些细致的规则.
| 归档时间: |
|
| 查看次数: |
466 次 |
| 最近记录: |