0

次のコードの最後の行でコンパイラ エラーが発生する理由を教えてください。

: 次の行を削除すると、コードはエラーなしでコンパイルされます。

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;
}
4

2 に答える 2

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) {}
};

次に、結果をテストします。ところで。intan を渡すコンストラクターが安全かどうかはわかりません。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;

正常に動作します-そして、それはあなたが達成しようとしていることだと思いますか? 2 つのバリアントが同等に比較可能であることをテストしたい (?) これは、バリアント内のすべてのオブジェクトが同等に比較可能である限り機能します。

于 2012-11-06T13:52:10.783 に答える
0

約:

しかし、appliedEqualityVisitor(compareValue)を呼び出すと、compareValueが何であっても、常にfalseが返されます。何か案が?

訪問者の使用法を誤解していると思いますが、演算子()は、バリアントパラメーター(例ではint)ではなく実際のバリアント型で呼び出されます。

編集:コード内

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

testValueは、訪問者をインスタンス化するときにMyVariantに変換されます。

平等ブーストリンクのブースト例

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) );

于 2012-11-06T15:16:42.963 に答える