C++ 为什么std::begin使用尾部返回类型语法?
范围访问功能C++ 为什么std::begin使用尾部返回类型语法?,c++,c++11,return,auto,decltype,C++,C++11,Return,Auto,Decltype,范围访问功能std::begin声明如下(对于容器): 模板 自动开始(C&C)->decltype(C.begin()); 我只是想知道为什么不简单 template< class C > decltype(C::begin) begin( C& c ); 模板 decltype(C::begin)begin(C&C); 这两者有什么区别吗 等效代码为 template< class C > decltype(::std::declval<C &am
std::begin
声明如下(对于容器):
模板
自动开始(C&C)->decltype(C.begin());
我只是想知道为什么不简单
template< class C >
decltype(C::begin) begin( C& c );
模板
decltype(C::begin)begin(C&C);
这两者有什么区别吗 等效代码为
template< class C >
decltype(::std::declval<C &>().begin()) begin( C& c );
模板
decltype(::std::declval().begin())begin(C&C);
它更长,并且可能更容易出错。此版本
template< class C >
decltype(C::begin) begin( C& c )
模板
decltype(C::begin)begin(C&C)
不行,因为
decltype(C::begin)
表示方法的类型,而不是方法调用结果的类型begin
方法是重载的,如果没有函数调用的上下文(即使没有计算),编译器将无法决定应该参与哪个重载VTT显示的
std::declval
版本通过创建一个可以解决重载的未评估函数调用上下文修复了这一问题。使用尾随的decltype
可以避免重复参数类型。尝试过吗?如果是,发生了什么?如果不是,为什么不呢?第一个版本在调用begin
时获取类型。第二个版本的类型是begin
C::begin
可能是一个成员函数,decltype(C::begin)
类似于Iterator(C::*)()
(指向成员函数的指针),这与Iterator
@DanielLangr不同-您的测试不正确。它通过ADL对向量调用std::begin
。请尝试使用范围解析法执行*::begin()
。@DanielLangr您可以使用:
预先设置自定义的begin
,或者将其重命名为my_begin
,以避免ADL,在这种情况下,您可以使用。
template< class C >
decltype(C::begin) begin( C& c )