Струнно-булевое сравнение — почему?

Я работал с boost::variant<int,std::string,bool> и его посетители, когда я столкнулся с неожиданным поведением: значения строки и bool были сопоставимы. Я не знаю, почему это работает так, но я нашел это интересным. Моя единственная идея состоит в том, что вариант со значением bool был интерпретирован как char? Кто-то может мне это объяснить?
Сравнение посетителя:

#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/variant.hpp>
#include <boost/function.hpp>

struct my_less : boost::static_visitor<bool*>
{
template<typename T>
bool* operator()(T a, T b) const
{
return a<b ? new bool(true) : new bool(false);
}

template<typename T, typename U>
bool* operator()(T a, U b) const
{
return NULL;
}
};

int main()
{
typedef boost::variant<int,bool,std::string> datatype;
datatype *a = new datatype(false);
datatype *b = new datatype("abc");

my_less cmp;

bool* val = boost::apply_visitor(cmp,*a,*b);

if(val)
{
std::cout << *val;
}
else
{
std::cout << "NULL";
}

}

РЕДАКТИРОВАТЬ
Вот расширенная основная функция с некоторыми тестами:

void show_result(bool* val)
{
if(val)
{
std::cout << *val << std::endl;
}
else
{
std::cout << "NULL" << std::endl;
}
}

int main()
{
//std::string a = "bbb";
//bool b = true;
//std::cout << b<a;      //compilation error

typedef boost::variant<int,bool,std::string> datatype;
datatype int_value_1(4);
datatype int_value_2(3);
datatype string_value("abc");
datatype bool_value(true);
my_less cmp;

std::cout<<"First result, compare ints 4 and 3:"<<std::endl;
bool* val = boost::apply_visitor(cmp,int_value_1,int_value_2);
show_result(val);

std::cout<<"Second result, compare int to string 4 to abc " << std::endl;
val = boost::apply_visitor(cmp,int_value_1,string_value);
show_result(val);

std::cout <<"Third result, int 4 to bool true:" << std::endl;
val = boost::apply_visitor(cmp,int_value_1,bool_value);
show_result(val);

std::cout<<"Fourth result, string abc to bool true" << std::endl;
val = boost::apply_visitor(cmp,string_value,bool_value);
show_result(val);

}

Выход:

First result, compare ints 4 and 3:
0
Second result, compare int to string 4 to abc
NULL
Third result, int 4 to bool true:
NULL
Fourth result, string abc to bool true
0

2

Решение

Хорошо, теперь, когда вы полностью изменили свою программу, позвольте мне попробовать еще раз.

Проблема в:

datatype *b = new datatype("abc");

"abc" это const char*не std::string, Если вы хотите создать std::string вариант, вам нужно сделать это явно. Иначе вы в конечном итоге создадите bool вариант, потому что все указатели конвертируются в bool, в том числе const char* указатели.

Попробуй это

datatype *b = new datatype(std::string("abc"));

Это взаимодействие между bool а также std::string очевидно хорошо известен и несколько раздражает. boost::variant предоставляет шаблонный конструктор, но правила разрешения предпочитают встроенный диалог bool и в C ++ нет способа указать специализацию шаблона для конструктора. Можно явно специализировать присваивание, поэтому вы можете написать:

datatype b;
b.operator=<std::string>("abc");

который может быть немного более эффективным, но гораздо менее читабельным, чем

datatype b;
b = std::string("abc");

Если вы не включите bool как вариант, строковые литералы автоматически конвертируются в std::string, Может быть, можно использовать какой-то прокси-псевдо-логический класс. Я никогда не пробовал.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]