Clang vs G ++左值到右值转换 [英] Clang vs G++ lvalue to rvalue conversion
问题描述
与此问题一个相关的问题。通过跟踪 slt_pair。 h
和移动。 h
,看来 Clang 和 G ++ 之间的区别是内部的。我尝试模拟对象(pair.first)的分配,与 std_pair.h
的实现相同,输出与 Clang
The question related to this one. By tracing slt_pair. h
and move. h
, it's seems that the difference between Clang and G++ is internally. I have tried to simulate the assignment of the object (pair.first) as same as the implementation of std_pair.h
, the output is same as Clang output it's reasonable output, but why when using pairs it's changes.
#include <iostream>
struct Foo {
Foo() {
std::cout << "default" << std::endl;
}
Foo(Foo& f2) {
std::cout << "non-const" << std::endl;
}
Foo(const Foo& f2) {
std::cout << "const" << std::endl;
}
};
// static_cast Foo lvalue to rvalue
Foo cast1(Foo foo){
return static_cast<Foo&&>(foo);
}
// same : check weather foo and Foo are the same type
Foo cast2(Foo foo){
return static_cast<typename std::remove_reference<Foo>::type&&>(foo);
}
int main() {
Foo T1; // pair Foo object
std::cout<<"Start"<<std::endl;
std::cout<<std::endl;
// (&&) rvalue casting
T1 = cast2(Foo()); // First pair object
std::cout << std::endl;
Foo const foo = T1;// Second pair object
}
Clang 如何处理从 lvalue
到 rvalue
的转换,真正的原因是什么这些不同的输出。
How Clang deals with conversion lvalue
to rvalue
and what the real reason for these different outputs.
感谢任何意见。
更新 :在接受的注释部分中,我得到了令人满意的答复。
Update: I have got a satisfying answers on the comments section of the accepted one.
推荐答案
我认为您示例中的所有内容都不能做什么你认为是的。返回中的 static_cast
是没有意义的, cast1
和 cast2 $ c的结果$ c>将自动为右值,因为您按值返回。此外,
cast1
和 cast2
在内部也是相同的,因为 std :: remove_reference_t< Foo>
只是 Foo
。如果您有进行模板工作,则需要 remove_reference
。
I think not everything in your example does what you think it does. The static_cast
in the returns is meaningless, the result of cast1
and cast2
will automatically be an rvalue since you return by value. Further, cast1
and cast2
are also internally identical since std::remove_reference_t<Foo>
is just Foo
. You would need remove_reference
if you had some templating going on.
此外,您正在将作业与构造混合在一起。在 T1 = cast2(Foo());
中会发生以下情况:
Furthermore, you are mixing assignments with constructions. In T1 = cast2(Foo());
the following happens:
- A未命名的临时文件由
Foo()
构造。这将输出default
- 该临时变量被复制到
foo
参数code> cast2 。这会输出const
,因为我们试图从一个临时对象构造一个Foo
对象,并且仅const Foo&
,而不是Foo&
,可以绑定到临时文件。 -
static_cast
几乎没有任何作用。 -
foo
被返回。通过返回值优化,不应调用应调用的构造函数。 - 我们使用默认(和隐式)赋值运算符
T1.operator =(const Foo&)
来分配返回值。
- A unnamed temporary is constructed by
Foo()
. This outputsdefault
- This temporary is copied to the
foo
argument ofcast2
. This outputsconst
, since we try to construct aFoo
object from a temporary, and onlyconst Foo&
, notFoo&
, can bind to a temporary. - The
static_cast
does pretty much nothing. foo
is returned. By return value optimization, the constructor that should be called, is not called.- We assign the returned value by using the default (and implicit) assignment operator
T1.operator=(const Foo&)
. Nothing gets printed.
在 Foo const foo = T1
中,您称为构造函数。由于 T1
是左值,因此您将调用构造函数 Foo(Foo&)
和 non -const
已打印。
In Foo const foo = T1
you call a constructor. Since T1
is an lvalue, you will call the constructor Foo(Foo&)
and non-const
is printed.
这篇关于Clang vs G ++左值到右值转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!