2015-12-11 1 views
0

Linked QuestionКак подобрать подходящие типы возвращаемого значения 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> 

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

+0

Почему не просто 'var = string_struct (string_param);' если вы знаете, что хотите инициализировать 'string_struct', а не' string' – SirGuy

+2

Кроме того, вы можете сделать конструктор «явным» и удалить неявное преобразование из 'const std :: string &'. – melak47

+0

О, да, я думаю, в моем комментарии не рассматривается вопрос о попытке инициализировать вариант строки ... Создание явного конструктора решит это, сделав мой первый комментарий необходимым, а не просто предложением. – SirGuy

ответ

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, потому что это то, что вы передали варианту.

EDIT

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

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

EDIT 2

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

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

+0

Итак, проблема заключается в том, что я требую, чтобы string_struct сохранял имя пользователя 'name'. –

+0

Я не уверен, что вы имеете в виду, в вашем примере ваша строка 'string_struct' содержит копию строки, используемой для ее построения, и мой пример. Я не уверен, что вы хотите сделать, если не это ... – SirGuy

+0

Откуда появляется имя в вашем примере? –

Смежные вопросы