当引入另一个构造函数时,复制构造函数在移动构造函数上选择

时间:2014-01-25 08:37:44

标签: c++11 visual-studio-2013 move-semantics

我正在努力解决一些我不理解的奇怪行为。下面我有一个最小的测试用例,可以重现我的问题。 X是一个具有移动语义的类。在下面的代码中,我希望X<false> f(std::move(t));导致对模板化移动构造函数的调用。但是,这会导致调用模板化复制构造函数。除非我删除第三个模板化构造函数,然后一切都按预期工作:

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));
}

是否有充分理由选择const X<C2>& other变种X<C2>&& other,或者这是Visual Studio 2013中的错误? 如果这是一个bug,有没有解决这个问题的想法(除了删除最后一个模板化的构造函数)?

1 个答案:

答案 0 :(得分:1)

我已在https://connect.microsoft.com/VisualStudio/feedback/details/814740/copy-constructor-chosen-over-move-constructor-when-another-constructor-is-introduced#

提交了Visual Studio 2013的错误报告

在那里报告了一种解决方法: 将模板X(F f)构造函数移动到其他模板化构造函数上方,然后调用正确的移动构造函数。