首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >boost.variant派生类型:不能使用复制构造函数

boost.variant派生类型:不能使用复制构造函数
EN

Stack Overflow用户
提问于 2017-02-24 19:00:29
回答 1查看 507关注 0票数 2

我有一个从boost::variant<T, E>派生的类型。我做了以下事情,并且我不能使用复制构造函数,我不知道为什么,一些SFINAE似乎失败了。看起来boost::variant<T, E>构造在继承的构造函数中接受了一个T作为ExpectedResult<T, E>。我怎样才能用最简单的解决方案修复它呢?

代码语言:javascript
运行
复制
template <class T, class E>
class ExpectedResult : boost::variant<T, E> {
public:
    using boost::variant<T, E>::variant;
};

ExpectedResult<int,float> er;
ExpectedResult<int, float> er2 = er;


error: no type named 'type' in 'boost::enable_if<boost::mpl::and_<boost::mpl::not_<boost::is_same<Emotiv::Cortex::Utilities::ExpectedResult<int, float>, boost::variant<int, float> > >, boost::detail::variant::is_variant_constructible_from<const Emotiv::Cortex::Utilities::ExpectedResult<int, float> &, boost::mpl::l_item<mpl_::long_<2>, int, boost::mpl::l_item<mpl_::long_<1>, float, boost::mpl::l_end> > >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, void>'; 'enable_if' cannot be used to disable this declaration
        typename boost::enable_if<mpl::and_<
                                  ^~~~~~~~~~
note: in instantiation of member function 'boost::variant<int, float>::variant' requested here
    using boost::variant<T, E>::variant;
    while substituting deduced template arguments into function template 'ExpectedResult' [with T = Emotiv::Cortex::Utilities::ExpectedResult<int, float>]
    ExpectedResult<int, float> er2 = er;
EN

回答 1

Stack Overflow用户

发布于 2017-02-24 23:50:39

Boost变体有一个完美的转发构造函数。

您正在将其导入到您的类中。

它通过检查self&是否是boost::variant来防止使用self。您正在向它传递一个ExpectedResult&

这就把它搞混了。

代码语言:javascript
运行
复制
template <class T, class E>
struct ExpectedResult : boost::variant<T, E> {
  using boost::variant<T, E>::variant;
  ExpectedResult()=default;
  ExpectedResult(ExpectedResult const&)=default;
  ExpectedResult(ExpectedResult &&)=default;
  ExpectedResult(ExpectedResult & o):
    ExpectedResult( const_cast<ExpectedResult const&>(o) )
  {}
  ExpectedResult(ExpectedResult &&)=default;
  ExpectedResult(ExpectedResult const&& o):
    ExpectedResult( o ) // calls const& ctor
  {}
  ExpectedResult& operator=(ExpectedResult const&)=default;
  ExpectedResult& operator=(ExpectedResult &&)=default;
  ExpectedResult& operator=(ExpectedResult &) {
    return *this=const_cast<ExpectedResult const&>(o);
  }
  ExpectedResult& operator=(ExpectedResult const&& o){
    return *this = o; // const& assign
  }
};

我怀疑上述默认的和手动编写的特殊成员函数可能会有所帮助。

要想完整,你还必须包含volatile,用另一个包来分解它。

在添加我自己的完美转发构造函数以及使用父构造函数时,我会非常小心,因为在C++17中,这些构造函数的更改规则可能会被破坏。我目前对使用继承的构造函数非常谨慎,因为我还不完全理解C++17中的突破性变化。

另一种方法是避免继承构造,而是转发到变体。

代码语言:javascript
运行
复制
template <class T, class E>
struct ExpectedResult : boost::variant<T, E> {
  using base=boost::variant<T, E>;
  ExpectedResult()=default;
  ExpectedResult(ExpectedResult const&)=default;
  ExpectedResult(ExpectedResult &&)=default;
  ExpectedResult(ExpectedResult &&)=default;
  ExpectedResult& operator=(ExpectedResult const&)=default;
  ExpectedResult& operator=(ExpectedResult &&)=default;

  template<class T0, class...Ts,
    class=std::enable_if_t<
      std::is_constructible<base, T0, Ts...>::value
      && (
        (sizeof...(ts)!=0)
        || !std::is_same<std::decay_t<T0>, ExpectedResult>::value
      )          
    >
  >
  ExpectedResult(T0&&t0, Ts&&...ts):
    base(std::forward<T0>(t0), std::forward<Ts>(ts)...)
  {}
};

这是一个完美的转发,有它所有的不完美之处,但对于大多数用途来说,它足够接近了。

initializer_list<T>, Ts&&...构造函数可以使完美的转发更加完美,所以ExpectedResult<std::vector<int>, bool> er{ {1,2,3,4} }是有效的。

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

https://stackoverflow.com/questions/42436968

复制
相关文章

相似问题

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