2013-04-18 2 views
3

Сегодня я испытал интересное поведение с пользовательскими операторами неявного преобразования.Пользовательский оператор неявного преобразования и разрешение перегрузки

Давайте возьмем этот кусок кода:

struct Widget { 
    Widget(uint64_t) { 

    } 

    Widget(const std::string &) { 

    } 

    operator uint64_t() { 
     return static_cast<uint64_t>(123456789UL); 
    } 

    operator std::string() { 
     return std::string("Hello"); 
    } 
}; 

Базовая структура, которая неявно могут быть преобразованы либо в uint64_t или станд :: строки.

Теперь попробуйте распечатать Widget экземпляр через станд :: соиЬ:

#include <iostream> 

int main() { 
    using std::cout; 
    Widget w(123456); 

    cout << w; 
} 

по какой-либо причине, виджет всегда будет преобразован в uint64_t. Сначала я ожидал бы призыв быть неоднозначным, и быть Qualifed со стандартным явным преобразованием для компиляции:

int main() { 
    using std::cout; 
    Widget w(123456); 

    cout << static_cast<uint64_t>(w); 

}

Но по причине я не обращая внимания прямо сейчас, выбран оператор uint64_t. Я попытался посмотреть спецификацию на C++, но не смог найти ничего полезного, чтобы ответить на мой вопрос.

Может ли кто-нибудь помочь мне разобраться, что делает компилятор с разрешением перегрузки?

ответ

2

uint64_t преобразование является предпочтительным. Причина в том, что << перегружен как шаблон для strings (basic_strings). Компиляторы всегда предпочитают точное совпадение над шаблонами при разрешении перегрузки.

+0

Спасибо, я не понял, что оператор << был перегружен как шаблон для std :: basic_string. Это все объясняет. Если я заменил std :: string на double, теперь он двусмыслен. – octal

+0

@octal http: //en.cppreference.com/w/cpp/string/basic_string/operator_ltltgtgt – stardust

3

Конечно, вы можете найти его в спецификации C++.

Read Разрешение перегрузки в §13.3.1/2 и §13.3.1/3

разрешение перегрузки выбирает функцию для вызова в семи различных контекстах в пределах языка ...

 

  • Во-первых, подмножество функций-кандидатов (те, которые имеют надлежащее количество аргументов и отвечают некоторым другим условиям), - это , выбранный для формирования набора жизнеспособных функций (13.3.2).
  • Тогда наилучшая жизнеспособная функция выбирается на основе неявных последовательностей преобразования (13.3.3.1), необходимых для сопоставления каждого аргумента с соответствующим параметром каждой жизнеспособной функции.

 

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

+0

Спасибо за реф. – octal

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