我有一个派生自 boost::variant<T, E>
的类型。我执行以下操作,但无法使用复制构造函数,我不明白为什么,一些 SFINAE
似乎失败了。看起来 boost::variant<T, E>
建筑正在吞噬T
如ExpectedResult<T, E>
在继承的构造函数中。
我怎样才能用最简单的解决方案修复它以使其正常工作?
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;
最佳答案
Boost 变体有一个完美的转发构造函数。
您正在将其导入到您的类(class)中。
它可以防止消耗 self&
通过检查是否 self
正是 boost::variant
。您正在向它传递 ExpectedResult&
.
这让人困惑。
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 中的重大更改,我目前对使用继承的构造函数非常谨慎。
另一种方法是避免继承构造,而是转发到变体。
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} }
有效。
关于c++ - boost.variant派生类型: cannot use copy constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42436968/