C++ C+;中decltype(this)的类型是什么+;?
显然,clang认为C++ C+;中decltype(this)的类型是什么+;?,c++,c++11,this,decltype,C++,C++11,This,Decltype,显然,clang认为decltype(this)是指向cv限定类的指针,而gcc认为它是指向cv限定类指针的常量引用。GCC只认为decltype(&*this)是指向cv限定类的指针。当它被用作模板的类型名时,这有一些含义。考虑一个假设的例子: template<typename T> class MyContainer { /* ... */ template<typename ContainerPtr> class MyIterator {
decltype(this)
是指向cv限定类的指针,而gcc认为它是指向cv限定类指针的常量引用。GCC只认为decltype(&*this)
是指向cv限定类的指针。当它被用作模板的类型名时,这有一些含义。考虑一个假设的例子:
template<typename T>
class MyContainer {
/* ... */
template<typename ContainerPtr>
class MyIterator {
ContainerPtr container;
/* ... */
};
auto cbegin() const
-> MyIterator<decltype(&*this)> { return { /* ... */ }; }
auto cend() const
-> MyIterator<decltype(this)> { return { /* ... */ }; }
};
模板
类霉菌容器{
/* ... */
模板
类迭代器{
集装箱运输集装箱;
/* ... */
};
自动cbegin()常量
->My迭代器{return{/*…*/};}
自动cend()常量
->My迭代器{return{/*…*/};}
};
在本例中,实现了一个自定义容器T
。作为一个容器,它支持迭代器。实际上,有两种迭代器:iterator
s和const\u迭代器
s。为这两个类复制代码是没有意义的,因此可以编写一个模板迭代器类,使用指向原始类的指针MyContainer*
或指向常量版本MyContainer const*
当
cbegin
和cend
一起使用时,gcc会出错,说它推导出了冲突的类型,而clang工作得很好。好的,下面是我在标准()中发现的:
7.1.6.2简单类型说明符[dcl.type.Simple]
4由decltype(e)
表示的类型定义如下:-如果
e
是未加密的id表达式或
未授权类成员访问(5.2.5),decltype(e)
是
由e
命名的实体的名称。如果没有此类实体,或者如果e
命名一组重载函数,则程序格式不正确-否则,如果
e
是一个x值,decltype(e)
是T&
,其中
T
是e
的类型-否则,如果
e
是左值,
decltype(e)
是T&
,其中T
是e
的类型- 否则,
decltype(e)
是
decltype
说明符是未赋值的操作数(第5条)
及
5.1.1概述[解释基本概述]
3如果声明声明了成员函数或成员函数
类的模板
X
,表达式this
是类型的prvalue
“指向可选cv限定符seq之间的cv限定符seqX
”的指针
函数定义、成员声明符或
声明人。它不应出现在可选cv限定符seq之前
且不应出现在静态成员的声明中
函数(尽管其类型和值类别在
静态成员函数,因为它们位于非静态成员中
功能)。[注意:这是因为不进行声明匹配
直到知道完整的声明符。-结束注释]与对象不同
表达式在其他上下文中,*此
不要求完整
类型用于在成员外部访问类成员(5.2.5)
功能体。[注:仅在
声明可见。-结束注释]
前面提到的§9.3.2是一个错误,因为它涉及成员函数的主体,如下所述
9.3.2“this”指针[class.this]
1在非静态(9.3)成员函数的主体中
关键字'this'是一个prvalue表达式,其值为的地址
为其调用函数的对象。a中“this”的类型
类`X`的成员函数是`X*`。如果成员函数为
声明为'const',如果成员
函数声明为'volatile',this'的类型为'volatile X*`,
如果成员函数声明为“const volatile”,则
`这是常数X*`。
所以看起来gcc是错误的。
这是一个PR值,所以decltype(this)
应该始终是普通的X*
(或者X cv*
/cv X*
)。添加const&
似乎是GCC(用g++4.8.1测试)中的一个错误,它只发生在类模板中(不是“普通”类),并且只发生在尾部返回类型中(不是在成员函数体中):。这在GCC4.9(实验版)中似乎是固定的,您可以进行测试。评估这个会给出一个右值。例如,您不能使用地址,如中的&this
。如果this
是常量引用,您可以获取地址。this
是X cv*
类型的prvalue,其中cv
对应于R my_foo()cv中的cv
代码>。你确定Clang认为这个是一个cv限定指针,而不是指向cv限定X
的指针吗?@Xeo,对不起,它应该是指向cv限定类的指针。好吧,显然促使我问这个问题的问题是非常具体和本地化的……注意:你最初的引用似乎来自一个旧的草稿(早于标准化之前的最后一份公开草案)。在实际的C++11标准中,7.1.6.2/4的最终措辞略有不同(最接近标准的草案是,基本上是C++11标准+)。因此,我建议进行编辑。但差异对问题没有影响。此答案不适用于问题!此
未在函数体中使用,因此§9.3.2与问题无关。规范的相关部分是§5.1.1/3。但无论如何,这是gcc<4.9中的一个缺陷。