Как обойти соответствующие возвращаемые типы Boost Variant?

Связанный вопрос

Предположим, у нас есть:

boost::variant<nil, std::string, string_struct>

А также,

struct string_struct
{
   string_struct(std::string const& name = "") : name(name) {}
   std::string name;
}

Есть ли какой-нибудь способ предотвратить неправильный вывод компилятором неверного типа варианта наддува?

Более теоретически, если бы мы имели

boost::variant<std::string, std::string>

Я не думаю, что это скомпилируется. Первый пример будет, однако. Проблема в том, как мы можем гарантировать отсутствие коллизий возвращаемых типов? В частности, когда используется как часть синтаксического анализатора, есть бесчисленные случаи, когда мы хотели бы первый пример. Так...

1 ответ

Этот код не проверен, но я уверен, что это решит вашу проблему.

    struct string_struct
    {
        explicit string_struct(const std::string & s):name(s){}
    };

    typedef boost::variant<nil, std::string, string_struct> var_t;

    var_t v1 = std::string("Hello");
    var_t v2 = string_struct("Hello");

var1 будет однозначно инициализирован для хранения строки, потому что для создания string_struct Вы должны вызвать его конструктор явно. var2 будет, конечно, инициализирован для хранения string_struct, потому что это то, что вы передали варианту.

РЕДАКТИРОВАТЬ

Хорошо, вам не хватает информации о типах правил и структур, которые вы добавили, поэтому я собираюсь сказать, что они должны быть добавлены к вашему вопросу. Я наконец нашел определения в вашем предыдущем вопросе.

Несмотря на то, что на данный момент, мое лучшее предположение на данный момент, что вы можете сделать, это заставить правило для идентификатора возвращать фактический идентификатор вместо строки (это действительно сбивает с толку иметь тип идентификатора и правило идентификатора, между прочим, но я понимаю, что ты не тот, кто это сделал).

РЕДАКТИРОВАТЬ 2

Вместо того, чтобы оставлять еще один комментарий, я выложу его здесь:

У тебя есть qi::rule<Iterator, std::string(), skipper<Iterator> > identifier;, который объявляет тип возвращаемого значения этого правила как std::string, Изменить это на qi::rule<Iterator, identifier(), skipper<Iterator> > identifier;, который объявляет тип возвращаемого значения правила как identifier, Обратите внимание на изменение от std::string в identifier, Дайте мне знать, если это поможет вам или вы уже сделали это.

Другие вопросы по тегам