考虑以下:
struct X
{
Y y_;
X(const Y & y) :y_(y) {}
X(Y && y) :y_(std::move(y)) {}
};
Run Code Online (Sandbox Code Playgroud)
是否有必要像第二个那样定义构造函数以充分利用移动语义?或者在适当的情况下会自动处理?
如何检查我的编译器是否支持右值引用?是否有标准的预处理器宏,或者不同的编译器有不同的宏?理想情况下,我想写这个:
#ifdef RVALUE_REFERENCES_SUPPORTED
foobar(foobar&& that)
{
// ...
}
#endif
Run Code Online (Sandbox Code Playgroud) 假设我有以下代码:
class B { /* */ };
class A {
vector<B*> vb;
public:
void add(B* b) { vb.push_back(b); }
};
int main() {
A a;
B* b(new B());
a.add(b);
}
Run Code Online (Sandbox Code Playgroud)
假设在这种情况下,B*可以处理所有原始指针unique_ptr<B>.
令人惊讶的是,我无法找到如何使用转换此代码unique_ptr.经过几次尝试,我想出了以下代码,它编译:
class A {
vector<unique_ptr<B>> vb;
public:
void add(unique_ptr<B> b) { vb.push_back(move(b)); }
};
int main() {
A a;
unique_ptr<B> b(new B());
a.add(move(b));
}
Run Code Online (Sandbox Code Playgroud)
所以我的简单问题是:这是实现它的方式,特别是,这是move(b)唯一的方法吗?(我在想rvalue引用,但我不完全理解它们.)
如果你有一个完整的移动语义解释链接unique_ptr,我无法找到,请不要犹豫,分享它.
编辑根据http://thbecker.net/articles/rvalue_references/section_01.html,我的代码似乎没问题.
实际上,std :: move只是语法糖.对于类X的对象x,move(x)与以下内容相同:
static_cast <X&&>(x)
Run Code Online (Sandbox Code Playgroud)
需要这两个移动函数,因为转换为右值引用:
以下示例应该编译吗?
struct B;
struct A
{
A(B*&&){}
};
struct B : A
{
B() : A(this){}
};
int main(){}
Run Code Online (Sandbox Code Playgroud)
在LWS上使用clang进行编译,但是使用gcc我得到:
没有已知的从'B*const'到'B*&&'的参数1的转换
如果我添加const它编译.
我还要指出MSVC也错了:
无法将参数2从'B*const'转换为'B*&&'
所以看起来我们在两个编译器中有一个bug.
BUGS FILED
我正在学习通过引用传递,这是我做的测试:
#include <iostream>
using namespace std;
int i = 0;
//If this is uncommented, compiler gives ambiguous definition error.
//void paramCheck (string s) {
// cout << ++i << ". Param is var.\n";
//}
void paramCheck (const string& s) {
cout << ++i << ". Param is const ref.\n";
}
void paramCheck (string& s) {
cout << ++i << ". Param is non-const ref.\n";
}
void paramCheck (const string&& s) {
cout << ++i << ". Param is const rvalue-reference.\n"; …Run Code Online (Sandbox Code Playgroud) 假设我有一个函数的两个重载f.f(T&&)和f(T&).然后在身体g:
g(T&& t) { f(t);}过载f(T&)将调用因为t被认为是左值.
这对我来说非常令人惊讶.带签名的函数如何f(T&&)与类型的调用不匹配T&&?让我更加惊讶的是,一个电话f(static_cast<T&&>(t))实际上会调用rvalue超载f(T&&).
使这成为可能的C++规则是什么?是T&&不是类型吗?
考虑到(x | r | l | pr | gl)值,我想到了以下问题:
考虑以下两个变量声明:
X x = ...;
Run Code Online (Sandbox Code Playgroud)
和
X&& x = ...;
Run Code Online (Sandbox Code Playgroud)
并承担了...做不提供的x值.
任何人都可以想到代码没有使用decltype,这会产生什么影响?在这两种情况下,(x)都会通过左值型X,不是吗?
比方说我有:
template<class T>
struct NodeBase
{
T value;
NodeBase(T &&value)
: value(value) { }
};
Run Code Online (Sandbox Code Playgroud)
我继承了它:
template<class T>
struct Node : public NodeBase<T>
{
Node(T &&value)
: NodeBase( WHAT_GOES_HERE (value)) { }
};
Run Code Online (Sandbox Code Playgroud)
应该WHAT_GOES_HERE是std::move和std::forward<T>?为什么?
我有以下测试程序:
#include <iostream>
#include <type_traits>
#include <utility>
template<typename Ty, std::size_t N>
void foo(Ty (&&)[N])
{
std::cout << "Ty (&&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty, std::size_t N>
void foo(Ty (&)[N])
{
std::cout << "Ty (&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty>
using id = Ty;
int main()
{
std::cout.setf(std::cout.boolalpha);
foo(id<int[]>{1, 2, 3, 4, 5});
foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE.
int xs[]{1, 2, 3, 4, 5};
foo(xs); …Run Code Online (Sandbox Code Playgroud) 我在std :: vector上有一些奇怪的行为,添加了rvalues:
#include <iostream>
#include <vector>
class A {
public:
A():i_{5}{std::cout << "default" << std::endl;}
A(const A &data) { std::cout << "copied!" << std::endl; }
A(A &&data) { std::cout << "moved " << std::endl; }
int i_;
};
int main(int argc, char *argv[]) {
std::vector<A> datavec;
datavec.push_back(A{});
datavec.push_back(A{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
default
moved
default
moved
copied!
Run Code Online (Sandbox Code Playgroud)
因此,矢量仍然创建A的副本,我做的越多 - 我得到的副本越多.但是,如果我用默认的A替换移动构造函数A(A && data)= default; 或用A删除复制构造函数(const A&data)= delete; 我得到了正确的结果,没有复制.如果我先调用足够大小的datavec.reserve,我也没有副本.我使用gcc版本5.4.0没有特定的参数
g++ -std=c++11 -o main ../main.cpp
Run Code Online (Sandbox Code Playgroud)
你有没有想过为什么矢量复制明显的右值?我希望这不是STL的一些错误
c++ ×10
rvalue-reference ×10
c++11 ×9
arrays ×1
const ×1
move ×1
rvalue ×1
unique-ptr ×1
vector ×1