将此指针分配给对指针的右值引用
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
”类型的引用由“cv2T2
”类型的表达式初始化,如下所示:[...]
[...] 或 引用应为右值引用。
如果初始化表达式
是一个 xvalue、类纯右值、数组纯右值或函数左值和 [...],或者
有一个类类型(即 T2 是一个类类型),[...]
然后[...]
否则,将使用非引用复制初始化 (8.5) 的规则从初始化表达式创建并初始化“cv1 T1”类型的临时变量。然后将引用绑定到临时文件。 [...]
【讨论】:
可能是因为你在构造函数中? @KerrekSB 我没有看到这样说的规则,但是,为什么这会使 pointerconst
?
嗯,从头开始...但请注意this
是一个表达式,而不是一个变量。这是一个prvalue。
@ArmenTsirunyan 这不是真的。 B* const
类型的纯右值不会绑定到 B*&&
,而 B*
类型的纯右值会。
我忘了还有3.10p4:non-class prvalues always have cv-unqualified types
。这意味着B*
的prvalue 永远不能是const
。以上是关于将此指针分配给对指针的右值引用的主要内容,如果未能解决你的问题,请参考以下文章