2013-07-15 4 views
1

У меня есть следующая функцияповышение :: получить повышение :: вариант не дает правильный вывод

template <typename T, typename U> 
const T* visitor_fct(U& operand) 
{ 
    return (boost::get<T>(&operand)); 
} 

Когда я

boost::variant<int, std::string> str = "string"; 
std::cout << visitor_fct<std::string>(str) << std::endl; 

Я получаю правильный вывод

Но когда я изменить объявление str на:

boost::variant<int, std::string, bool> str = "toto";

Я всегда получаю nullptr;

Почему?

ответ

2

Причина заключается в том, что строковый литерале (char*) преобразуется в bool лучше, чем std::string так ваша строке буквальной не инициализировать string составляющей варианты, но вместо bool компонента (истина).

См следующее выдающее bool 1:

#include <iostream> 

void foo(bool b) 
{ 
    std::cout << "bool " << b << std::endl; 
} 

void foo(std::string s) 
{ 
    std::cout << "string " << s << std::endl; 
} 

int main() 
{ 
    foo("Bar"); 
} 

Initializing с std::string("toto") решит вашу проблему.

4,12/1 показывает нам преобразование в вопрос:

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a 
prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; 
any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of 
type bool; the resulting value is false. 

[Как было отмечено также в другой ответ] Это неявное преобразование имеет приоритет над конвертерной конструктора std::string и так выбран, в результате чего тип используемого в варианте будет bool.

2

То, что происходит здесь, состоит в том, что в варианте boost :: присутствует bool, const const *, который вы передаете, больше не используется для строки, а скорее преобразуется в bool.

, если вы измените эту строку:

boost::variant<int, std::string, bool> str = "toto"; 

к этому:

boost::variant<int, std::string, bool> str = std::string("toto"); 

он будет работать.

Вот почему bool выбирается по строке: неявные преобразования происходят между любыми типами указателя и bool, и преобразования между встроенными типами всегда предпочтительнее, чем пользовательские преобразования. И поскольку std :: string - это определенный пользователем тип (стандартный ум, но все же определенный пользователем), bool выигрывает над строкой.