Создать статически типизированный вариант в C ++ 0x - PullRequest
0 голосов
/ 22 марта 2011

Мне интересно, возможно ли в C ++ 0x создать статически типизированный вариант (который ведет себя как auto):

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

Когда мы присваиваем v значению, отличному от int, ононе компилируется:

v = true; //Compile error

Пока я не нашел ни одного элегантного решения.

Ответы [ 3 ]

6 голосов
/ 22 марта 2011

Этот код компилируется на моей машине с Boost.Variant и g ++ 4.5 для C ++ 98 и C ++ 0x.Вы хотите реализовать вариантный тип самостоятельно?Тогда вы можете взглянуть на реализацию 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>, и вы получите идеальную переадресацию и правильное поведение для целочисленного продвижения.

2 голосов
/ 22 марта 2011

Я думаю, это невозможно.

После создания объекта его статический тип не содержит никакой информации, связанной с инициализацией объекта.Не имеет значения, для инициализации использовались int или bool, тип переменной тот же:

variant<int, bool, std::string>

Оператор присваивания может анализировать содержимое только во время выполнения и генерировать исключение, если это необходимо.

1 голос
/ 22 марта 2011

Нет, я не думаю, что вы можете сделать это во время компиляции.

Вы можете включить или отключить набор операторов присваивания, используя enable_if или аналогичный, но для каждого типа, а не для каждого экземпляра. При компиляции v = true в одном модуле компиляции, как мы можем узнать, какой конструктор вы использовали в другом модуле компиляции?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...