【问题标题】:overloaded constructor illegal with move and copy移动和复制重载构造函数非法
【发布时间】:2015-07-31 07:28:50
【问题描述】:

我正在编写一个类,它将为其构造函数之一采用特殊类型,该类型可以是任何符合我要求的类型。我遇到了这个模板化构造函数导致我的复制和移动构造函数是非法重载的问题!

我的班级是这样布置的:

template<typename ... Types>
class myclass{
    public:
        myclass(const myclass &other){/* copy constructor */}
        myclass(myclass &&other){/* move constructor */}

        template<typename Special>
        myclass(Special &&arg){/* stops copy/move implementations */}
}

我怎样才能绕过这个限制?

【问题讨论】:

  • 我猜你的意思是 myclass(Special &amp;&amp;arg) 对于非 const 左值参数比复制构造函数更受欢迎?
  • @PiotrSkotnicki 是的,我愿意

标签: c++ templates c++14 forwarding-reference


【解决方案1】:

约束它。

template<typename Special,
         std::enable_if_t<!std::is_same<std::decay_t<Special>, myclass>{}, int> = 0 >
myclass(Special &&arg) { /* ... */ }

根据您的特定用例,您可能还希望进一步将 Special 限制为仅符合您要求的类型。

【讨论】:

  • 我不知道为什么我只是随机忘记了 SFINAE。我会接受这个作为答案
【解决方案2】:

这个例子展示了不同的情况:

const myclass c1(42);      // special: int
myclass c2(c1);            // copy
myclass c3(c2);            // special: myclass& (non const)
myclass c4(std::move(c3)); // move

Live Demo

您的复制/移动构造函数仍然是合法的重载,但非 const l-value 与您的模板构造函数完全匹配。

你可以:

  • 使用 SFINAE 在模板中禁止myclass&amp;(如 T.C 的回答)
  • 提供另一个重载(完全匹配):

    myclass(myclass &other) : myclass(static_cast<const myclass &>(other)) {}
    

    Demo

【讨论】:

  • 这似乎更像是一个评论而不是一个答案
  • @CoffeeandCode:我正在用小部分写我的答案。
  • 这不会处理myclass c5(std::move(c1));
  • @T.C.:const myclass&amp;&amp; 的其他重载是可能的。不确定这个案例是否有意义......
  • @Jarod42 处理迭代器的通用代码,您想在其中执行auto c = std::move(*it); 之类的操作,但仍然可以使用 const 迭代器。
猜你喜欢
  • 2023-03-20
  • 2023-03-11
  • 2023-03-28
  • 1970-01-01
  • 2018-09-23
  • 2013-11-05
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多