将此指针分配给对指针的右值引用

Posted

技术标签:

【中文标题】将此指针分配给对指针的右值引用【英文标题】:Assigning this pointer to rvalue reference to a pointer 【发布时间】:2013-03-21 21:36:53 【问题描述】:

是否应该编译以下示例?

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 *&&'

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

已提交错误

MSVC bug link

GCC bug link

【问题讨论】:

供参考 - 这在英特尔 C++ 编译器 (13.1) 上编译 【参考方案1】:

是的,应该可以编译。

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

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

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

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

这里很明显你不能修改this(比如this = nullptr),但也清楚没有const对于这样的解释是必要的。 (而您在构造函数中的值只是临时值。)

【讨论】:

真的指定了不能修改this吗?显然,当它是纯右值时我们不能,但是如果我们将它绑定到右值引用并通过它修改它呢? 有趣,所以这意味着the selected answer to this SO question 错了? @GManNickG 我想通了。将右值引用绑定到this 将首先创建它的临时副本,然后绑定到它。所以原来的this指针实际上不会受到影响。 @sftrabbit:是的!同:int&& x = 0;. @GmanNickG 是的,我刚试过int&& x = 5; x++;,有一段时间我以为我已经改变了数学本身。现在我们将学习用 1, 2, 3, 4, 6, 6, 7, ... 来数数。【参考方案2】:

我说 clang 是对的 - 代码应该可以编译。出于某种原因,GCC 将this 指针视为const,尽管有以下情况:

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

所以在这种情况下,this 应该是纯右值B* 并且可以完美绑定到B*&&。但是,请注意,当将this 绑定到右值引用时,this 的值将被复制到临时对象中,而引用将被绑定到该对象。这可确保您永远不会真正修改原始 this 值。

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

[...]

[...] 或 引用应为右值引用

如果初始化表达式

是一个 xvalue、类纯右值、数组纯右值或函数左值和 [...],或者

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

然后[...]

否则,将使用非引用复制初始化 (8.5) 的规则从初始化表达式创建并初始化“cv1 T1”类型的临时变量。然后将引用绑定到临时文件。 [...]

【讨论】:

可能是因为你在构造函数中? @KerrekSB 我没有看到这样说的规则,但是,为什么这会使 pointer const? 嗯,从头开始...但请注意this 是一个表达式,而不是一个变量。这是一个prvalue。 @ArmenTsirunyan 这不是真的。 B* const 类型的纯右值不会绑定到 B*&&,而 B* 类型的纯右值会。 我忘了还有3.10p4:non-class prvalues always have cv-unqualified types。这意味着B* 的prvalue 永远不能是const

以上是关于将此指针分配给对指针的右值引用的主要内容,如果未能解决你的问题,请参考以下文章

C++智能指针之shared_ptr与右值引用(详细)

C++智能指针之shared_ptr与右值引用(详细)

C++智能指针之shared_ptr与右值引用(详细)

让函数指针模板参数接受右值引用是不是合法?

重新理解C11的右值引用

如何评价 C++11 的右值引用(Rvalue reference)特性?