C++:为什么decltype(*this)返回一个引用?

13
template<typename T>
struct foo{
    void f(){
        decltype(*this) a(*this);
        do_some_test(a);
    }
    T data;
};
//compiler won't accept this

在我看来,decltype应该返回一种类型,以便我们可以在声明中使用它。但谷歌说,在decltype(x)中,如果x是一个左值,它将返回T&,其中T是x的类型。
但他们设计它返回引用是为了什么?此外,在模板中如何创建与*this类型相同的类的实例?

还有一个关于如何使用decltype创建新实例的问题 使用new和decltype - Fsmv
“但是他们设计它返回一个引用的目的是什么?”每个表达式都有一个值类别(lvalue、xvalue或prvalue)。decltype通过应用引用限定符来反映该属性:对于lvalue表达式,使用左值引用限定符;对于xvalue,使用右值引用限定符;对于prvalue,则不使用引用。 - dyp
是的,链接应该是一个答案。对于重复造成的不便,我们深表歉意。 - sqd
1个回答

25

decltype会推导出表达式的类型,除非它应用于一个变量,在这种情况下,它将推导出该变量的类型:

decltype(e)表示的类型定义如下:

— 如果e是未括号化的id表达式或未括号化的类成员访问,则decltype(e) 是由e命名实体的类型。如果不存在这样的实体或者e命名了一组重载函数,则程序就是非法的;

— 否则,如果e是一个xvalue,decltype(e)T&&,其中Te 的类型;

— 否则,如果e 是一个lvalue,decltype(e)T&,其中Te的类型;

— 否则,decltype(e)e的类型。

§7.1.6.2 [dcl.type.simple]

对指针进行解引用将产生一个lvalue,因此decltype将推断出指向对象的类型的左值引用:

一元运算符*执行间接寻址:施加于它的表达式必须是一个指向对象类型或函数类型的指针,其结果是一个左值引用,指向该表达式所指的对象或函数。

§5.3.1 [expr.unary.op]

因此,对于某个指针pdecltype(*p)推断出指向该指针指向的对象类型的左值引用。

如果您想从某个指针p获取指向对象的类型,则可以使用:

std::remove_pointer<decltype(p)>::type

或者:

std::remove_reference<decltype(*p)>::type

或者,在您的示例中,您可以简单地说foo,不需要类型推断。

6
或者在C++14中,您可以直接使用std :: remove_reference_t <decltype(*p)>,无需冗长的std :: remove_reference <decltype(*p)>::type。 - PapaDiHatti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接