Может кто-нибудь сказать мне, почему я получаю ошибку компилятора для последней строки следующего кода?
нота: Если я удалю следующую строку, мой код будет скомпилирован без ошибок:
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;
}
Проблема связана с вашим классом посетителей. 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) {}
};
Затем проверьте результат. Btw. Я не уверен, что ваш конструктор, которому вы передаете 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;
Работает нормально — и я думаю, что это то, что вы пытаетесь достичь? Вы хотите проверить, что два варианта одинаково сопоставимы (?) Это будет работать до тех пор, пока все объекты в вашем варианте одинаково сопоставимы.
Около:
Но когда я вызываю applyEqualityVisitor (compareValue), он всегда возвращает
false, независимо от того, что является CompareValue. Любая идея?
Я думаю, что вы неправильно поняли использование посетителей, оператор () вызывается с фактическим типом варианта, а не с параметром варианта (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) );