Reputation: 212
I am struggling with some weird behaviour that I do not understand. Below I have a minimal testcase that reproduces my problem. X is a class that has move semantics. In the code below, I expect that X<false> f(std::move(t));
results in a call to the templated move constructor. However, this results in a call to the templated copy constructor. Except when I remove the third templated constructor, then everything works as expected:
template<bool C>
class X
{
public:
X() {}
X(const X& other) {}
X(X&& other) {}
template<bool C2>
X(const X<C2>& other) {} // This constructor is actually being called
template<bool C2>
X(X<C2>&& other) {} // I expected this constructor to be called
template<class F>
X(F f) {} // If this constructor is removed, the expected constructor is called, removing my confusion
};
void testX()
{
X<true> t;
X<false> f(std::move(t));
}
Is there a good reason why the const X<C2>& other
variant is picked over X<C2>&& other
, or is this a bug in Visual Studio 2013?
If this is a bug, are there any ideas for working around this problem (other than removing the last templated constructor)?
Upvotes: 0
Views: 90
Reputation: 212
I have submitted a bug report for Visual Studio 2013 at https://connect.microsoft.com/VisualStudio/feedback/details/814740/copy-constructor-chosen-over-move-constructor-when-another-constructor-is-introduced#
A workaround was reported there: Move the template X(F f) constructor above the other templated constructors, and then the correct move constructor is called.
Upvotes: 1