Чи може оператор приведення бути явним?


84

Що стосується конструкторів, додавання ключового слова explicitзаважає захопленому компілятору створювати об'єкт, коли це не було першим наміром програміста. Чи доступний такий механізм і для операторів кастингу?

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

Ось, наприклад, я хотів би мати можливість відіграти Fooроль std::string, але я не хочу, щоб такий актор відбувся неявно.

Відповіді:


101

Так і ні.

Це залежить від того, яку версію С ++ ви використовуєте.

  • 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():-).
James Kanze

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.