【发布时间】:2014-04-17 15:14:04
【问题描述】:
这是在 Visual Studio 2010 上,使用 Boost v1.48.0。我正在尝试使用一些结构和指向结构的共享指针来获得 boost::variant 以匹配 boost::static_visitor 的正确成员,但没有成功......
对于我的问题,让我们建立这个前提,例如:
struct t_type_A { int key; foo value; };
struct t_type_B { int key; bar value; };
struct t_type_C { int key; baz value; };
struct t_type_D { int key; qux value; };
bool operator<(const t_type_A &, const t_type_A &);
bool operator<(const t_type_B &, const t_type_B &);
bool operator<(const t_type_C &, const t_type_C &);
bool operator<(const t_type_D &, const t_type_D &);
bool operator==(const t_type_A &, const t_type_A &);
bool operator==(const t_type_B &, const t_type_B &);
bool operator==(const t_type_C &, const t_type_C &);
bool operator==(const t_type_D &, const t_type_D &);
typedef std::shared_ptr<t_type_C> t_shared_C;
typedef std::shared_ptr<t_type_D> t_shared_D;
typedef boost::variant<t_type_A, t_type_B, t_shared_C, t_shared_D> t_variant;
我有一个访客如下:
class variant_less : public boost::static_visitor<bool>
{
public:
template<typename T>
result_type operator()(const T &left, const T &right) const
{
return left.value < right.value || (left.value == right.value && left.key < right.key);
}
template<typename T, typename U>
result_type operator()(const T &left, const U &right) const
{
return left.key < right.key;
}
template<typename T>
result_type operator()(const std::shared_ptr<T> &left, const std::shared_ptr<T> &right) const
{
return left->value < right->value || (left->value == right->value && left->key < right->key);
}
template<typename T, typename U>
result_type operator()(const std::shared_ptr<T> &left, const std::shared_ptr<U> &right) const
{
return left->key < right->key;
}
};
在实践中,当我将访问者应用于我的变体时,我会收到如下编译器错误:
编辑:我不得不再次查看错误消息。我把它误译成这个例子,它不是在抱怨“价值”而是“关键”。错误已在下面修复。
错误 C2039:“key”:不是“std::tr1::shared_ptr<_ty>”的成员
编译器将两个 t_shared_C 或两个 t_shared_D 之间的比较解析为:
template<typename T, typename U>
result_type operator()(const T &left, const U &right) const
成为最合适的人选。这显然不是我想要的。或者,根据我对 SFINAE 的不可靠知识,我尝试了以下方法:
class variant_less : public boost::static_visitor<bool>
{
public:
template<typename T>
result_type operator()(const T &left, const T &right) const
{
return left.value < right.value || (left.value == right.value && left.key < right.key);
}
template<typename T, typename U>
result_type operator()(const T &left, const U &right) const
{
return left.key < right.key;
}
template<typename T>
result_type operator()(const T &left, const T &right) const
{
return left->value < right->value || (left->value == right->value && left->key < right->key);
}
template<typename T, typename U>
result_type operator()(const T &left, const U &right) const
{
return left->key < right->key;
}
};
我做错了什么?我不想放弃并为每个组合编写重载。
编辑:这是它的调用方式:
typedef boost::multi_index::multi_index_container<
t_variant_vector,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<variant_extractor<1234>, variant_less>
, boost::multi_index::ordered_non_unique<variant_extractor<5678>, variant_less>
// arbitrarily more indexes go here
>
> t_variant_multi_index;
向量是变体的排序向量,按键排序。这些索引是由具有特定“关键”值的变体的存在来索引的。 variant_extractor 查找并提取具有匹配键的变体。简要介绍一下 mult_index 所做的事情,然后将“键提取器”(一个变体)的结果用作“比较谓词”variant_less 的参数,用于对该索引进行排序。
【问题讨论】:
-
您的描述似乎不正确。你说它解析为
result_type operator()(const T &left, const U &right) const,但那个根本不使用value,所以它似乎选择了不同的重载。 -
这看起来不像
boost::static_visitor。那些需要带有单个参数的operator()。 -
@dyp Boost static_visitor 确实支持二元运算符。
-
请告诉我们您是如何尝试调用这些
operator()。 -
@Dave S 我明白你的意思了。
标签: c++ templates boost visual-c++-2010 boost-variant