将此指针指定给指针的右值引用

时间:2013-03-21 21:36:54

标签: c++ c++11 rvalue-reference

以下示例是否应该编译?

struct B;
struct A
{
  A(B*&&){}
};

struct B : A
{
  B() : A(this){}
};

int main(){}

LWS上使用clang进行编译,但是使用gcc我得到:

  

参数1从'B * const'到'B *&&'

没有已知的转换

如果我添加const,它就会编译。

我还想指出MSVC也错了:

  

无法将参数2从'B * const'转换为'B *&&'

所以看起来我们在两个编译器中有一个错误。

BUGS FILED

MSVC bug link

GCC bug link

2 个答案:

答案 0 :(得分:8)

是的,那应该编译。

this实现为cv T* const是不正确的(其中cv是函数的cv限定符,如果有的话,T是类类型)。 this不是const,而只是内置类型的prvalue表达式(不可修改)。

很多人认为,因为你不能修改this它必须是const,但正如Johannes Schaub - litb很久以前评论的那样,更好的解释是这样的:

// by the compiler
#define this (__this + 0)

// where __this is the "real" value of this

很明显,您无法修改this(例如,this = nullptr),但也请注意,此类说明无需const。 (而你在构造函数中的值只是临时值。)

答案 1 :(得分:6)

我说clang是对的 - 代码应该编译。出于某种原因,GCC认为this指针为const,尽管如下:

  

this的成员函数中X的类型为X*。如果成员函数声明为const,则其类型为const X*,如果成员函数声明为volatile,则其类型为volatile X*,如果成员函数声明为const volatile,其类型为const volatile X*

因此,在这种情况下,this应为prvalue B*,并且与B*&&完全绑定。但是,请注意,在将this绑定到右值引用时,this的值将被复制到临时对象中,而引用将被绑定到该对象。这可确保您永远不会实际修改原始this值。

  

对类型“cv1 T1”的引用由类型为“cv2 T2”的表达式初始化,如下所示:

     
      
  • [...]

  •   
  • [...]或引用应为右值参考

         
        
    • 如果是初始化表达式

           
          
      • 是xvalue,类prvalue,数组prvalue或函数左值和[...],或

      •   
      • 有一个类类型(即T2是类类型),[...]

      •   
           

      然后[...]

    •   
    • 否则,使用非参考拷贝初始化(8.5)的规则,从初始化表达式创建并初始化类型为“cv1 T1”的临时类型。然后将引用绑定到临时。 [...]

    •   
  •