0

C ++ 0xで静的に型付けされたバリアント(autoのように動作する)を作成できるかどうか疑問に思っています:

variant<int, bool, std::string> v = 45;

vをint以外の値に割り当てると、コンパイルされません。

v = true; //Compile error

これまでのところ、私はエレガントな解決策を見つけていません。

4

3 に答える 3

6

このコードは、C++98 と C++0x の両方について、Boost.Variant と g++ 4.5 を使用して私のマシンでコンパイルされます。バリアント型を自分で実装しますか? 次に、Boost の実装を調べることができます。

上記の動作を /get/ したい場合は、次のようにすることができます:

auto v = 45;
static_assert(std::is_same<decltype(v), bool>
              || std::is_same<decltype(v), int>
              || std::is_same<decltype(v), std::string>,
              "v must be int, bool or string");

これは、あなたが説明したものとまったく同じはずです。

以下は、クリントンの提案を実装しています。

template <typename T, typename... Args>
struct has_type;

template <typename T, typename Head, typename... Args>
struct has_type<T, Head, Args...>
{
    static const bool value = std::is_same<T, Head>::value
                              || has_type<T, Args...>::value;
};

template <typename T>
struct has_type<T> : std::false_type
{};

template <typename... Args, typename T>
T&& check_type (T&& t)
{
    static_assert(has_type<T, Args...>::value, "check_type");
    return std::move(t);
}

<memory>これにはとだけが必要で<type_traits>、完全な転送と整数昇格の正しい動作が得られます。

于 2011-03-22T08:21:36.367 に答える
2

私は、これは不可能だと思います。

オブジェクトが作成された後、その静的型にはオブジェクトの初期化に関連する情報は含まれません。int または bool が初期化に使用されたかどうかは関係ありません。変数の型は同じです。

variant<int, bool, std::string>

代入演算子は、実行時にのみコンテンツを分析し、必要に応じて例外をスローできます。

于 2011-03-22T08:35:14.987 に答える
1

いいえ、コンパイル時にそれを行うことはできないと思います。

enable_if などを使用して代入演算子のセットを有効または無効にすることができますが、インスタンスごとではなくタイプごとになります。あるコンパイル単位で v = true をコンパイルするとき、別のコンパイル単位で使用したコンストラクタをどのように知ることができますか?

于 2011-03-22T08:36:24.727 に答える