And*_*iel 4 c++ multithreading rvalue-reference c++11
我有一个创建的两个类cl1,cl2并cl1有一个带cl2&参数的构造函数.我有三个函数,一个cl1作为参数,一个cl1&&作为参数,一个cl1&作为参数.
#include <thread>
#include <iostream>
class cl1;
class cl2;
class cl2 {
public:
int y;
cl2(int y) : y(y) {} //ctor
};
class cl1 {
public:
int x;
cl1(int x) : x(x) {} //ctor
cl1(cl2& ob1) : x(ob1.y * 2) {} //ctor for automatic conversion of cl2& to cl1, x = y*2
};
void do_work_with_cl(cl1 ob) { //This works as usual by actually copying the object through the conversion constructor
std::cout << "The x of ob is " << ob.x << std::endl;
}
void do_work_with_cl_rref(cl1&& ob) { //I guess this works because it takes an rvalue and the automatic
//conversion ctor of cl1 does just that
std::cout <<"Inside the function that takes cl1 as rvalue, x of ob is" << ob.x << std::endl;
}
void do_work_with_cl_lref(cl1& ob) { //This doesn't work as ob is non-const lvalue reference
std::cout << "lvalue referenced but the object created through implicit conversion is temporary(i.e rvalue)" << std::endl;
}
int main() {
//Normal non-threaded calls
cl2 ob(100); //create a cl2 object
do_work_with_cl(ob); //This is ok
do_work_with_cl_rref(ob); //This too works
//do_work_with_cl_lref(ob) //This fails, as suspected
std::cout << "Thread part" << std::endl
//Now calling the functions through a thread
std::thread t1(do_work_with_cl_rref, ob); //Thought this could work here, but doesn't
//The other functions also don't work, but I can understand why.
t1.join();
}
Run Code Online (Sandbox Code Playgroud)
在ideone.com:http://ideone.com/MPZc4C,我要问这个问题,例如工作.但是使用g ++ - 4.7我得到一个错误:
In file included from /usr/include/c++/4.7/ratio:38:0,
from /usr/include/c++/4.7/chrono:38,
from /usr/include/c++/4.7/thread:38,
from main.cpp:1:
/usr/include/c++/4.7/type_traits: In instantiation of ‘struct std::_Result_of_impl<false, false, void (*)(cl1&&), cl2>’:
/usr/include/c++/4.7/type_traits:1857:12: required from ‘class std::result_of<void (*(cl2))(cl1&&)>’
/usr/include/c++/4.7/functional:1563:61: required from ‘struct std::_Bind_simple<void (*(cl2))(cl1&&)>’
/usr/include/c++/4.7/thread:133:9: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(cl1&&); _Args = {cl2&}]’
main.cpp:13:44: required from here
/usr/include/c++/4.7/type_traits:1834:9: error: invalid initialization of reference of type ‘cl1&&’ from expression of type ‘cl2’
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)
我真的不知道它是否与实现或代码有任何问题.我只是在学习C++中的线程和东西,所以没有实际的理由我为什么这样做.请告诉我这是什么问题,如果我在代码的评论中是正确的.(代码中的"This works ......"注释意味着当从main()中将对象作为参数(不是对它的引用)调用时,它们是好的.)
C++标准第30.3.1.2/3段说:
"要求:F和Args中的每个Ti应满足MoveConstructible要求.INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)(20.8.2)应为有效表达式".
表达式DECAY_COPY(x)在30.2.6中定义:
"在本条款的几个地方使用了该操作DECAY_COPY(x).所有这些用途都意味着调用函数decay_copy(x)并使用结果,其decay_copy定义如下:"
template <class T> typename decay<T>::type decay_copy(T&& v)
{ return std::forward<T>(v); }
Run Code Online (Sandbox Code Playgroud)
由于decay操作从物体移除cv修饰符,需要有一个普遍有效的从类型转换构造函数或转换运算符cl1输入cl2.要检查这一点,转发机制std::thread显然会生成rvalue引用cl1并尝试从中获取实例c2.这会失败,因为rvalue引用不能绑定到转换构造函数中的非const左值引用.
如果你将构造函数的签名更改cl1(cl2& ob1)为cl1(cl2 const& ob1)它可以使用GCC 4.7.2,因为rvalue引用可以绑定到左值引用const.
| 归档时间: |
|
| 查看次数: |
282 次 |
| 最近记录: |