我最近发现,当用作返回类型时,decltype表达式作为函数符号名称的一部分被破坏,并且这可能是导致令人讨厌的分段错误,同时解析表达式(例如在调试会话中),如果表达式是太复杂了.
第一个版本,在函数返回类型中使用decltype,其中完整表达式被破坏(http://goo.gl/EALubx):
#include#include struct A { void bar() const; }; template decltype(std::declval ().bar()) foo(T const& a); void foo() { A a; return foo(a); }
编译为(GCC 5.2.0):
foo(): sub rsp, 24 lea rdi, [rsp+15] call decltype ((((declval)()).bar)()) foo(A const&) add rsp, 24 ret
第二个版本,几乎等效,其中表达式类型作为附加模板参数的一部分被解析(http://goo.gl/DfQGR5):
#include#include struct A { void bar() const; }; template ().bar())> R foo(T const& a); void foo() { A a; return foo(a); }
编译为(GCC 5.2.0):
foo(): sub rsp, 24 lea rdi, [rsp+15] call void foo(A const&) add rsp, 24 ret
我知道模板函数只能在它们的返回类型上重载,但是编译器不应该能够自己解析decltype表达式而是破坏结果类型吗?
任何人都可以告诉我为什么,或者指出我在C++规范中指定的位置?