Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于C++;std::thread中的自动类型转换行为_C++_Multithreading_C++11_Rvalue Reference - Fatal编程技术网

C++ 关于C++;std::thread中的自动类型转换行为

C++ 关于C++;std::thread中的自动类型转换行为,c++,multithreading,c++11,rvalue-reference,C++,Multithreading,C++11,Rvalue Reference,我创建了两个类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 {

我创建了两个类
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();                                              
}
#包括
#包括
cl1类;
cl2类;
cl2类{
公众:
int-y;
cl2(int-y):y(y){}//
};
cl1类{
公众:
int x;
cl1(intx):x(x){}//
cl1(cl2&ob1):x(ob1.y*2){}//用于将cl2&自动转换为cl1的向量,x=y*2
};
void do_work_with_cl(cl1 ob){//这与通常一样,通过转换构造函数实际复制对象

STD::CUT< P>第30. 3.1.2/3的C++标准表示:

“Requires:F和Args中的每个Ti应满足可移动的构造要求。INVOKE(
detacy\u COPY(std::forward(F))、detacy\u COPY(std::forward(Args))…)
(20.8.2)应为有效表达式”

表达式<代码>衰变副本(x)
在30.2.6中定义:

“在本条款的几个地方,使用了操作
DECAY\u COPY(x)
。所有这些用法都意味着调用函数
DECAY\u COPY(x)
,并使用结果,其中
DECAY\u COPY
的定义如下:”

模板类型名称衰减::类型衰减\u副本(T&v)
{return std::forward(v);}
由于
decay
操作会从对象中删除cv限定符,因此需要有一个通用有效的转换构造函数或从类型
cl1
到类型
cl2
的转换操作符。要检查这一点,
std::thread
的转发机制显然会生成对的右值引用e> cl1并尝试从中获取
c2
的实例。这将失败,因为右值引用无法绑定到转换构造函数中的非常量左值引用


如果您将构造函数的签名从
cl1(cl2&ob1)
更改为
cl1(cl2 const&ob1)
它适用于GCC 4.7.2,因为右值引用可以绑定到左值引用到
const

到底是什么问题?顺便说一句,上面的代码在vs2012更新1中构建得很好。@claptrap我得到错误的原因,以及我的评论中的推理是否有任何错误。前一个是主要原因不过,还是要估计一下。哦,谢谢你的通知,我还没有在vs2012上测试过,我正在使用linux。tl;dr:总是定义正确的转换构造函数,引用
常量
,然后向所有创建一个非
常量
引用的构造函数的人射击。如果你需要修改原始对象中的某些内容,那么你就做错了什么-或者你需要一些可变的
@Griwes:holy words,只是一个小小的更正:那不是一个复制构造函数,而是一个转换构造函数啊..明白了。非常感谢你的解释(以及幕后工作)!我想知道为什么ideone和vs2012的代码(如claptrap所说)不过可以吗?@Andariel:他们可能有不同的线程支持库实现,不执行右值引用的转换。我个人认为GCC的方法更符合标准,但我可能错了
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
template <class T> typename decay<T>::type decay_copy(T&& v)
{ return std::forward<T>(v); }