c++ - 仅当底层类型具有这些构造函数时才实现模板类型构造函数

标签 c++ c++11 templates typetraits

有没有一种方法可以将类型封装在模板类中(类似于 std::optional),它具有所有必要的特殊构造函数和赋值运算符(即复制构造函数/赋值,移动ctor/assignment),但只有在底层类型具有这些功能时才“启用”它们? type_traits 中的函数(如 std::is_copy_constructible)看起来可能会有所帮助,但我不确定如何使用它们来实现此目标。作为引用,我尝试实现的类型类似于 std::optional 但替代值只是“无”,我想使用自定义错误类型。例如

template <typename T>
class ErrorOr {
 public:
  enum class Error {
    FATAL,
    WARNING,
    NONE,
  };

  ErrorOr(T val) : val(val), error(Error::NONE) {}
  ErrorOr(Error error) : error(error) {}

  // TODO: Implement copy/move ctors/assignment operators that only
  // exist if they do for the underlying T

  T get() { val; }

 private:
  T val;
  Error error;
};

这是一个非常简单/最小的实现,没有很多必要的功能,但希望能说明我要表达的观点。

这在 C++11 中可能吗?

最佳答案

在这种情况下,什么都不做。 ErrorOr<T>拥有类型为 T 的成员将默认所有特殊成员函数做正确的事。如果T不可复制,ErrorOr<T>也不会。


但是,这也不是真正的可选类型,因为您总是有一个 T .如果您最终转向有条件地具有 T 的实现, 一种方法是从一个空类型继承,该类型根据需要启用或禁用特殊成员。

一个简化的版本是:

template <bool allowCopies>
struct copy_enabler {
    copy_enabler() = default;
    copy_enabler(copy_enabler const& ) = default;
    copy_enabler& operator=(copy_enabler const& ) = default;
};

template <>
struct copy_enabler<false> {
    copy_enabler() = default;
    copy_enabler(copy_enabler const& ) = delete;
    copy_enabler& operator=(copy_enabler const& ) = delete;
};

然后你可以简单地:

template <typename T>
class ErrorOr : private copy_enabler</* is T copyable */> { ... };

在实践中,您将希望对所有特殊成员函数执行此操作,并添加一个标记类型,这样如果您对多个不同的类模板使用此技巧,它们就不会共享一个公共(public)基类。

关于c++ - 仅当底层类型具有这些构造函数时才实现模板类型构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48389981/

相关文章:

C++ 函数重写不起作用?

C++ 命令行调试参数

c++ - 为什么 C++ 不像 HTML/HTML5 那样移动到 'unversioned model'?

c++ - 使用显式实例化设置类模板的方法

c++ - 在 C++ 中从 const int 转换为 int

c++ - 如何在 CMake 项目中正确包含库

c++ - 为什么 Alexandrescu 不能使用 std::uncaught_exception() 在 ScopeGuard11 中实现 SCOPE_FAIL?

c++ - 需要帮助使用 switch 语句创建函数和错误

c++ - 如何使用 get std::bind 之类的行为

c++ - "Undefined reference to"模板类构造函数