2012-11-06 97 views
0

有人能告诉我为什么我在下面代码的最后一行出现编译器错误?Boost:使用apply_visitor比较变体

:如果我删除以下行,我的代码被没有错误编译:

appliedEqualityVisitor(compareValue); 

下面是代码:

#include "boost/variant/variant.hpp" 
#include "boost/variant/apply_visitor.hpp" 

using namespace std; 
using namespace boost; 


template<typename T> 
struct CheckOneTypeEquality : public boost::static_visitor<> 
{ 
    T const* value; 
    bool operator()(T const& other) const 
    { 
     return other == *value; 
    } 
    template<typename U> 
    bool operator()(U const& other) const 
    { 
     return false; 
    } 
    CheckOneTypeEquality(T const& value_):value(&value_) {} 
}; 

typedef variant<int, string> MyVariant; 
typedef apply_visitor_delayed_t<CheckOneTypeEquality<MyVariant>> AppliedEqualityVisitorType; 

int main(int argc, char **argv) 
{ 
    int testValue = 12; 
    CheckOneTypeEquality<MyVariant> equalityVisitor(testValue); 

    AppliedEqualityVisitorType appliedEqualityVisitor = apply_visitor(equalityVisitor); 

    MyVariant compareValue = 13; 
    appliedEqualityVisitor(compareValue); // <<<<< compile error here 

    return 0; 
} 
+0

发生时错误的升压例子吗? –

+1

@Meysam boost :: variant提供'operator ==',因此可以使用'operator =='比较同一个变体的两个实例,前提是每个有界类型都符合EqualityComparable概念 – mark

+0

@mark你是对的。我有点误导了! – Meysam

回答

1

的问题,从您的访问者类茎。 Boost期望void operator()(...),而你提供返回一些东西的operator()

对于你的模式工作,你将不得不改变的游客,是这样的:

template<typename T> 
struct CheckOneTypeEquality : public boost::static_visitor<> 
{ 
    T const* value; 
    mutable bool check; 
    void operator()(T const& other) const 
    { 
     check = other == *value; 
    } 
    template<typename U> 
    void operator()(U const& other) const 
    { 
     check = false; 
    } 
    CheckOneTypeEquality(T const& value_):value(&value_), check(false) {} 
}; 

然后测试结果。顺便说一句。我不确定你在那里通过int的构造函数是否安全。你没有持有该引用,而是指向到由int构建的变体的临时实例 - 这可能超出了范围。

编辑:我认为你试图做的是错误的,因为boost::variant已经正确实施operator==。例如:

MyVariant testValue = 12; 

MyVariant compareValue = 13; 
MyVariant compareValue2 = 12; 
MyVariant compareValue3 = "12"; 

std::cout << (compareValue == testValue) << std::endl; 
std::cout << (compareValue2 == testValue) << std::endl; 
std::cout << (compareValue3 == testValue) << std::endl; 

工作正常 - 我认为这是你正在试图完成的?你想测试两个变体是否具有同等的可比性(?)只要变体中的所有对象具有相同的可比性,这就会起作用。

+0

你说得对。我也可以通过将'boost :: static_visitor <>'改成'boost :: static_visitor '来摆脱错误。这样我cal仍然有bool返回值。它是[“二进制访问”](http://www.boost.org/doc/libs/1_52_0/doc/html/variant/tutorial.html) – Meysam

+0

但是当我调用'appliedEqualityVisitor(compareValue)'它总是返回false,不管'compareValue'是什么。任何想法? – Meysam

+0

@Meysam,看我的更新。 – Nim

0

关于:

But when I call appliedEqualityVisitor(compareValue) it always returns false, no matter what the compareValue is. Any idea?

我想你是误会游客的使用,运营商()调用与实际的变体具有一个变体的参数(在你的例子INT)不会打字。

编辑: 在代码

int testValue = 12; 
CheckOneTypeEquality<MyVariant> equalityVisitor(testValue); 

实例访问者当测试值被转换为MyVariant。

平等boost link

class are_strict_equals 
    : public boost::static_visitor<bool> 
{ 
public: 

    template <typename T, typename U> 
    bool operator()(const T &, const U &) const 
    { 
     return false; // cannot compare different types 
    } 

    template <typename T> 
    bool operator()(const T & lhs, const T & rhs) const 
    { 
     return lhs == rhs; 
    } 

}; 

boost::variant< int, std::string > v1("hello"); 

boost::variant< double, std::string > v2("hello"); 
assert(boost::apply_visitor(are_strict_equals(), v1, v2)); 

boost::variant< int, const char * > v3("hello"); 
assert(!boost::apply_visitor(are_strict_equals(), v1, v3)); 

+0

这与OP试图实现的内容不同(我相信),问题似乎是如何比较同一变体的两个实例...代码示例中的 – Nim

+0

v1和v2实例进行了比较,但它们必须是相同的类型(int和long例如总是返回false)。 – Marius