以下是代码段:
int i=0;
int&&k=std::move(i);
Run Code Online (Sandbox Code Playgroud)
在c ++入门中,此举是
template <typename T>
typename remove_reference<T>::type &&move(T&& t)
{return static_cast<typename remove_reference<T>::type&&>(t);}
Run Code Online (Sandbox Code Playgroud)
据我所知,这个std::move模板会扣除一个像这样的函数
int&& move(int& t){return static_cast<int&&>(t);}
Run Code Online (Sandbox Code Playgroud)
作为比较和阐述我的问题,请考虑这样的示例:
int test(int k){k=66;return k;}
int k;
int a=test(k);
Run Code Online (Sandbox Code Playgroud)
上面的代码将编译为:
int temp;//the temporary object
temp=k;
int a=temp;
Run Code Online (Sandbox Code Playgroud)
同样,我认为第一个代码片段将被编译为:
int&& temp=0;
int&& k=temp;//oop!temp is an lvalue!
Run Code Online (Sandbox Code Playgroud)
这似乎是错误的,因为它temp是一个左值,我有什么不对吗?
看这个简单的例子:
template <typename T>
const T const_create() {
return T();
}
struct Foo { };
int main() {
auto &x = const_create<Foo>(); // compiles
// auto &x = const_create<int>(); // doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
为什么版本可以Foo编译,而int不能编译?换句话说,为什么const要从返回类型中删除const_create<int>?它的工作方式就像它返回一样int,不是const int。这不是语言上的矛盾吗?
标准在哪里规定这种行为?
我以为我已经设法完全理解(在其他SO问题的帮助下,谢谢)关于值类别的C ++ 17的更改,但是现在我注意到了这个问题,这表明我不太了解它们。
在C ++ 11中,对值类别有“具有身份/可以从中移出”的解释,并且cppreference中仍然存在“身份”的含义的定义:
具有同一性:可以通过比较对象的地址或它们标识的功能(直接或间接获得)来确定该表达式是否与另一个表达式引用相同的实体。
在C ++ 17中,“具有身份/可以从其移出”不再成立,但是新定义也基于“身份”的概念:
glvalue(“广义” lvalue)是一个表达式,其求值确定对象,位字段或函数的身份;
我的问题/误解是:这是“身份”的相同意思,还是不同的“身份”?据我了解,c ++ 17中的情况如下:
A f() { return A(); }
A a = f(); // 1: f() is a prvalue expression, used to directly initialize a.
f(); // 2: f() is a prvalue expr., converted to xvalue by temporary materialization
A&& r = f(); // 3: f() is a prvalue expr., converted to xvalue by temporary materialization
Run Code Online (Sandbox Code Playgroud)
在第二和第三种情况下,我获得一个xvalue,这意味着它应该具有一个标识。因此,我应该能够得到它的地址 [编辑:]我应该能够确定它是否与某些其他表达式引用相同的实体,但是我认为我不能。当然,在第三种情况下,我可以将“&r”作为单独的命令执行,然后将其地址与另一个表达式的地址进行比较,但这是因为A &&是左值。是通过A &&取得地址,在这种情况下,“直接或间接获得”是什么意思?我认为这不是正确的答案,因为在C ++ 11中,我也可以轻松地做到
A&& r = …Run Code Online (Sandbox Code Playgroud) 据我所知,在 c++17 中,纯右值的概念/语义不再是临时对象,因此在许多情况下强制执行复制省略。
如果表达式是纯右值,则函数返回的对象将直接由该表达式初始化。当类型匹配时,这不涉及复制或移动构造函数
为什么“对象”一词出现在这里?在值类别中,不是引用类型的函数的返回属于纯右值,所以我认为使用术语对象可能是不合适的。
根据我的理解,纯右值现在不再是对象,它们只是值,对吗?
作为补充,这里也使用术语“对象”。
我应该参考lambda以避免复制吗?
这段代码会复制lambda吗:
auto myLambda = []() {/* do stuff */ }
Run Code Online (Sandbox Code Playgroud)
如果是的话,我应该这样写吗:
auto &myLambda = []() {/* do stuff */ }
Run Code Online (Sandbox Code Playgroud)
PS:很抱歉,有人用谷歌搜索了一个可能是新手的问题,但没有找到答案。
我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分
void push_back(object &&x) {
//do something
objects[size++] = std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?
另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:
A& operator=(A&& other) {
member = std::move(other.member);
return *this;
}
Run Code Online (Sandbox Code Playgroud) 当函数参数的类型为lvalue时lref:
void PrintAddress(const std::string& lref) {
std::cout << &lref << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
并且lref与一个prvalue绑定:
PrintAddress(lref.substr() /* temporary of type std::string */)
Run Code Online (Sandbox Code Playgroud)
地址代表什么?那里住着什么?
prvalue无法获取其地址.但是对 prvalue 的左值引用可以得到它的地址,这对我很好奇.
我有下面的代码段,其中i声明一个称为变量pval,其尝试导出T&&上的T*[与T被int].根据类型信息[使用abi解码],导出的类型是int*.
但是当我比较它的int*类型时,decltype(pval)它返回零而不是1,这意味着它被视为pval不同的类型int*.那么哪一个是由报告的错误pval存在或哪个指示比较为错误.int*typeidis_same
#include<iostream>
#include<string>
#include<typeinfo>
#include<cxxabi.h>
#include<type_traits>
using namespace std;
std::string classname(const std::type_info& info)
{
int status;
char* rslt=abi::__cxa_demangle(info.name(),0,0,&status);
std::string result(rslt);
free(rslt);
return result;
}
int main(int argc, char* argv[])
{
int* ptr = new int(10);
decltype(std::move(ptr)) pval = std::move(ptr);
cout << classname(typeid(pval)) << endl; // as per typeid information the type of pval is …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
int x;
int& f() {
return x ? x : throw 0;
}
Run Code Online (Sandbox Code Playgroud)
随着gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)我得到以下编译错误:
cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
Run Code Online (Sandbox Code Playgroud)
请注意,这在clang中编译得很好.以下是(我相信的)标准中的相关陈述:
N4659 [8.16.2.1](条件运算符):
第二个或第三个操作数(但不是两个)是一个(可能带括号的)throw-expression(8.17); 结果是另一个的类型和值类别.
据我所知,x是一个左值,所以在我看来clang是对的.我错了吗?
c++ g++ conditional-operator language-lawyer value-categories
遵循这个问题的公认答案Do rvalue references allow dangling references?当分配给右值引用左值时,xvalues 的生命周期似乎没有延长,就像问题中一样。但是,当我这样做时
#include <iostream>
using namespace std;
class Something {
public:
Something() {
cout << "Something()" << endl;
}
Something(const Something&) {
cout << "Something(const Something&)" << endl;
}
Something(Something&&) {
cout << "Something(Something&&)" << endl;
}
~Something() {
cout << "~Something()" << endl;
}
int a;
};
Something make_something() {
return Something{};
}
int main() {
auto&& something = make_something().a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调用返回的对象的生命周期make_something被延长,即使make_something().a是根据http://en.cppreference.com/w/cpp/language/value_category的 xvalue (xvalues …