Может ли оператор приведения быть явным?

84

Когда дело доходит до конструкторов, добавление ключевого слова explicitпредотвращает создание объекта энтузиастом компилятора, когда это не было первым намерением программиста. Доступен ли такой механизм и для операторов приведения?

struct Foo
{
    operator std::string() const;
};

Здесь, например, я хотел бы иметь возможность Fooпреобразовать в std::string, но я не хочу, чтобы такое преобразование происходило неявно.

qdii
источник

Ответы:

101

Да и нет.

Это зависит от того, какую версию C ++ вы используете.

  • C ++ 98 и C ++ 03 не поддерживают explicitоператоры преобразования типов.
  • Но C ++ 11 делает.

Пример,

struct A
{
    //implicit conversion to int
    operator int() { return 100; }

    //explicit conversion to std::string
    explicit operator std::string() { return "explicit"; } 
};

int main() 
{
   A a;
   int i = a;  //ok - implicit conversion 
   std::string s = a; //error - requires explicit conversion 
}

Скомпилируйте его g++ -std=c++0x, вы получите эту ошибку:

prog.cpp: 13: 20: ошибка: запрошено преобразование из 'A' в нескалярный тип 'std :: string'

Онлайн-демонстрация: http://ideone.com/DJut1

Но как только напишете:

std::string s = static_cast<std::string>(a); //ok - explicit conversion 

Ошибка уходит: http://ideone.com/LhuFd

Кстати, в C ++ 11 оператор явного преобразования называется «оператором контекстного преобразования», если он преобразуется в логическое значение . Кроме того, если вы хотите узнать больше о неявных и явных преобразованиях, прочтите этот раздел:

Надеюсь, это поможет.

Наваз
источник
9
Даже в C ++ 03 легко избежать неявного преобразования. Просто вызовите функцию toString, а не operator std::string. Конечно, это может вызвать проблемы с некоторыми шаблонами. Я всегда использовал toString, и это никогда не доставляло мне проблем, но я полагаю, что это может зависеть от вашего стиля программирования.
Джеймс Канце
@MatthieuM. Прямо как operator std::string():-).
Джеймс Канце
2
Я использую to_stringвместо этого. Помогает то, что это то, что C ++ 11 называет, поэтому он помогает писать код с прямой совместимостью и помогает с шаблонами.
Луис Мачука,
1
std::string s(a)или std::string s{a}также должен работать как static_cast<std::string>(a).
alfC
2
@Bin: потому что компилятор explicit operator bool() вызывает контекстно , когда вы пишете if(std::cin). Обратите внимание, что происходящее здесь преобразование (неформально) называется контекстным преобразованием, а не неявным преобразованием.
Nawaz