Paragraph Β§ 30.3.1.2/3 of the C ++ Standard states:
"Required: F and each Ti in Args must satisfy MoveConstructible. INVOKE ( DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) (20.8. 2) is a valid expression. "
The expression DECAY_COPY(x) defined in 30.2.6:
"In several places in this section, the DECAY_COPY(x) operation is used. All such uses mean calling the DECAY_COPY(x) function and using the result, where decay_copy is defined as follows:"
template <class T> typename decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); }
Since the decay operation removes the cv qualifiers from the object, cl2 must be a universally valid conversion constructor or conversion operator from type cl1 type cl1 . To test this, the std::thread transport mechanism apparently generates rvalue references to cl1 and tries to get c2 instances from them. This fails because rvalue links cannot be bound to a non-const reference link in the conversion constructor.
If you change the signature of your constructor from cl1(cl2& ob1) to cl1(cl2 const& ob1) , it works with GCC 4.7.2 because rvalue links can be bound to const lvalue links.
source share