2

boost::variant<int,std::string,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
4

1 に答える 1

4

プログラムを完全に変更したので、もう一度試してみましょう。

問題は:

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

"abc"ではconst char*なく、std::stringです。バリアントを作成する場合std::stringは、明示的に行う必要があります。そうしないと、ポインターを含むboolすべてのポインターが に変換できるため、バリアントを作成することになります。boolconst char*

これを試して

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

と の間のこの相互作用はboolstd::string明らかによく知られており、やや苛立たしいものです。boost::variantテンプレート化されたコンストラクターを提供しますが、解決規則は組み込みの変換を優先boolし、コンストラクターでテンプレートの特殊化を指定する方法は C++ にはありません。代入を明示的に特殊化することができるので、次のように書くことができます:

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

これはわずかに効率的ですが、より読みにくいかもしれません

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

バリアントとして含めない場合bool、文字列リテラルは自動的に に変換されstd::stringます。ある種のプロキシ擬似ブールクラスを使用することは可能かもしれません。私は試したことがない。

于 2013-01-17T04:04:23.683 に答える