2012-11-06 95 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