首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SFINAE删除副本构造函数

SFINAE删除副本构造函数
EN

Stack Overflow用户
提问于 2015-04-03 10:07:09
回答 3查看 1.6K关注 0票数 16

在某些情况下,我希望SFINAE去掉类模板的复制构造函数和复制赋值操作符。但是,如果这样做,就会生成一个默认的复制构造函数和一个默认赋值操作符。SFINAE是基于我作为类模板参数传递的标记完成的。问题是,SFINAE只在模板上工作,而复制构造函数/赋值运算符不能是模板。有解决办法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-03 10:22:28

此解决方案使用一个有条件不可复制的基类(通过将复制构造函数和复制赋值操作符明确标记为已删除)。

代码语言:javascript
复制
template <bool>
struct NoCopy;

template <>
struct NoCopy<true>
{
   // C++11 and later: marking as deleted. Pre-C++11, make the copy stuff private.
   NoCopy(const NoCopy&) = delete;
   NoCopy& operator=(const NoCopy&) = delete;
   protected:
      ~NoCopy() = default; // prevent delete from pointer-to-parent
};

template <>
struct NoCopy<false>
{
   // Copies allowed in this case
   protected:
      ~NoCopy() = default; // prevent delete from pointer-to-parent
};

示例用法:

代码语言:javascript
复制
template <typename Number>
struct Foo : NoCopy<std::is_integral<Number>::value>
{
   Foo() : NoCopy<std::is_integral<Number>::value>{}
   {
   }
};

int main()
{
   Foo<double> a;
   auto b = a; // compiles fine
   Foo<int> f;
   auto g = f; // fails!
}

注意:为了避免虚拟继承,NoCopy的析构函数被声明为protected (谢谢提示,@Yakk)。

票数 14
EN

Stack Overflow用户

发布于 2015-04-03 10:21:56

从可复制或不可复制的基础派生的方法是这类问题的标准成语(也请参阅Stefan的评论)。实现它的一种方法是这样的:

代码语言:javascript
复制
template<bool> struct copyable
{
protected:
  ~copyable() = default;
};

template<> struct copyable<false> 
{
  copyable(copyable const&) = delete;
  copyable&operator=(copyable const&) = delete;
protected:
  ~copyable() = default;
};

template<bool allow_copy>
class some_class : copyable<allow_copy> { /* ... */ };
票数 7
EN

Stack Overflow用户

发布于 2019-08-23 21:04:25

在C++20中,我们可以使用requires子句来约束特殊的成员函数:

代码语言:javascript
复制
template <typename T>
class C {
public:
    // ...
    C(const C&) requires std::is_copy_constructible_v<T> // for example
    {
        // ...
    }
    C(C&&) requires std::is_move_constructible_v<T> // for example
    {
        // ...
    }
    // ...
};

一个requires子句并不使函数成为函数模板,因此这些函数仍然限定为特殊成员函数,并阻塞生成的默认特殊成员函数。您甚至可以拥有多个,例如,复制构造函数,只要它们有不同的约束。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29430090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档