3

次のコンパイルが行われないのはなぜですか。

void f(int8_t a)
{
}

void f(int16_t a)
{
}

typedef boost::variant<int8_t, int16_t> AttrValue;

int main()
{
    AttrValue a;
    a = int8_t(1);
    f(a);
}

コンパイラエラーの場合:

error C2665: 'f' : none of the 2 overloads could convert all the argument types
could be 'void f(int8_t)'
or 'void f(int16_t)'

ただし、これは問題ありません。

std::cout << a; // f(a);

std :: ostream&operator <<(std :: ostream&、const AttrValue&)はどこで定義され、なぜ定義されているのですか?

4

3 に答える 3

9

オーバーロードの解決は、インスタンスにいずれかの型が含まれている可能性があるコンパイル時に発生するため、コンパイラはまたはboost::variantを呼び出すかどうかを知る方法がありません。void f(int8_t)void f(int16_t)

std::cout << aどちらの場合もstd::ostream &operator<<(std::ostream &, const AttrValue &)、インスタンスのランタイムタイプで内部ディスパッチする同じ関数を呼び出しているために機能します。

ディスパッチを実行するには、ビジターを作成する必要があります。

struct f_visitor: public boost::static_visitor<void>
{
    template<typename T> void operator()(T t) const { return f(t); }
};

boost::apply_visitor(f_visitor(), a);
于 2012-08-09T12:38:52.563 に答える
2

さて、あなたがa自分自身に割り当てていることの一つのために。そして、どのオーバーロードもboost::variant型をとらないので、もちろんコンパイラーは正しい関数を見つけることができません。

また、boost::get値を取得するために使用する必要がある場合があります。

f(boost::get<int8_t>(a));
于 2012-08-09T12:39:46.193 に答える
0

operator<<に対して定義されていることが発生するboost::variantため、コンパイラは暗黙的な型変換を実行する必要はありません。f()一方、関数の場合、どの変換を選択するかはわかりません。

于 2012-08-09T12:41:17.180 に答える