提升::变体与包含值的比较
boost::variant comparison with contained value
我正在尝试找到一种方法来比较 boost::variant 与底层值,而无需从该基础值构造变体。该问题在"main()"函数的注释中定义辅助问题是关于代码中定义的比较运算符。如何减少比较运算符的#?如果 boost::variant 包含 6 种不同的类型,我必须定义 6 种吗!操作员能够比较两个变体?
谢谢!
#include <boost/variant.hpp>
namespace test {
namespace Tag {
struct Level1{ int t{ 1 }; };
struct Level2{ int t{ 2 }; };
}
template <typename Kind> struct Node;
using LevelOne = Node<Tag::Level1>;
using LevelTwo = Node<Tag::Level2>;
using VariantNode = boost::variant
<
boost::recursive_wrapper<LevelOne>,
boost::recursive_wrapper<LevelTwo>
>;
typedef VariantNode* pTree;
typedef std::vector<pTree> lstTree;
template <typename Kind> struct Node
{
Node(pTree p, std::string n) : parent(p), name(n) {}
Node(const Node& another) : name(another.name), parent(another.parent) {}
virtual ~Node() {}
std::string name;
pTree parent;
};
bool operator == (const LevelOne& one, const LevelTwo& two) {
return false;
}
bool operator == (const LevelTwo& two, const LevelOne& one) {
return false;
}
bool operator == (const LevelOne& one, const LevelOne& two) {
return true;
}
bool operator == (const LevelTwo& one, const LevelTwo& two) {
return true;
}
}
int main(int argc, char *argv[])
{
using namespace test;
LevelOne l1(nullptr, "level one");
VariantNode tl2 = VariantNode(LevelTwo(nullptr, "level two"));
VariantNode tl1 = VariantNode(LevelOne(nullptr, "level one"));
bool rv = (tl1 == tl2); // this line compiles OK (comparing two variants)
// comparison below does not compile, because "l1" is not a variant.
// Question: How can I compare "variant" value "tl1"
// with one of the possible content values "l1"
bool rv1 = (tl1 == l1);
return 1;
}
以下内容适用于变体中的任意数量的类型:
template<typename T>
struct equality_visitor : boost::static_visitor<bool> {
explicit constexpr equality_visitor(T const& t) noexcept : t_{ &t } { }
template<typename U, std::enable_if_t<std::is_same<T, U>::value>* = nullptr>
constexpr bool operator ()(U const& u) const {
return *t_ == u;
}
template<typename U, std::enable_if_t<!std::is_same<T, U>::value>* = nullptr>
constexpr bool operator ()(U const&) const {
return false;
}
private:
T const* t_;
};
template<
typename T,
typename... Ts,
typename = std::enable_if_t<
boost::mpl::contains<typename boost::variant<Ts...>::types, T>::value
>
>
bool operator ==(T const& t, boost::variant<Ts...> const& v) {
equality_visitor<T> ev{ t };
return v.apply_visitor(ev);
}
template<
typename T,
typename... Ts,
typename = std::enable_if_t<
boost::mpl::contains<typename boost::variant<Ts...>::types, T>::value
>
>
bool operator !=(T const& t, boost::variant<Ts...> const& v) {
return !(t == v);
}
问题是比较必须始终是value == variant
或value != variant
的形式,而不是variant == value
或variant != value
。这是因为boost::variant<>
本身将这些算子定义为始终static_assert
,我们没有办法使全局算子比variant<>
的内置算子更专业。
在线演示
相关文章:
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- C++17:使用 std::optional 来评估枚举是否包含值
- 如何在两个列表中比较和获取非包含值
- 比较LLVM值的类型
- 编译器在这里做什么,允许在很少进行实际比较的情况下比较许多值
- 通过查看程序集来比较按值传递与按引用传递性能
- 在 64 位英特尔架构中比较uint8_t值是否比比较uint32_t慢
- 如何知道unordered_map<T*>包含值?
- 为什么我不能声明同时具有模板容器和模板包含值的类型?
- 类属性不包含值
- 比较输入值和从文件中读取值的最佳方式
- 比较包含格式化数据的字符串
- 字符串比较返回值(Is用于对字符进行排序的应用程序?)
- 我如何比较base36值在c++
- 为什么可以切换只能比较const值
- 包含值地址的字符串 ->该值的指针
- 仅当数组中尚未包含值时,才向数组添加值
- 如何找到包含值及其在 c++ 中出现的向量的分位数
- 提升::变体与包含值的比较
- 比较包含十六进制值C++的Char