Оператор преобразования C ++ и разрешение перегрузки - PullRequest
3 голосов
/ 08 февраля 2012

Данный пример содержит несколько перегрузок:

#include <iostream>

class T
{
   public:
      operator const wchar_t *(void) const
      {
         std::cout << "Conversion" << std::endl;
         return L"Testing";
      }
};

template <class Elem>
class A
{
};

template <class T>
void operator <<(A<T> &, const T *)
{
   std::cout << "1" << std::endl;
}

template <class T>
void operator <<(A<T> &, const void *)
{
   std::cout << "2" << std::endl;
}

int main(void)
{
   A<wchar_t> test;
   T          source;

   test << L"1";
   test << static_cast<const wchar_t *>(source);
   test << source;
}

И его вывод:

1
Conversion
1
Conversion
2

Мой вопрос - почему void operator <<(A<T> &, const void *) вызывается для утверждения test << source;?Кто-нибудь может привести конкретную часть стандарта, которая охватывает этот случай?

Ответы [ 3 ]

4 голосов
/ 08 февраля 2012

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

test << source;

, компилятор не смог найти подходящий T для первой функции шаблон; он пытается найти T такой, что T const* имеет то же самое введите T, что невозможно. Аргументация дедукции не удается, и создание экземпляра шаблона не добавляется в набор перегрузки. поскольку во втором параметре второго аргумента шаблона нет шаблон функции, нет аргумента вычета, чтобы потерпеть неудачу, и результирующая реализация становится единственным членом набора перегрузки, и так в конечном итоге быть выбранным.

0 голосов
/ 08 февраля 2012

Неявное вычитание аргументов шаблона не учитывает определенные пользователем неявные преобразования. Таким образом, вызов template <class T> void operator <<(A<T> &, const T *) вывел бы T на wchar_t из первого аргумента, но второй аргумент - T вместо const wchar_t*. Поэтому компилятор не сможет соответствовать этому оператору.

Для template <class T> void operator <<(A<T> &, const void *) дело выглядит иначе: T будет выведено равным wchar_t из первого аргумента функции. Второй аргумент может быть неявно преобразован в const wchar_t* определенным пользователем преобразованием, которое затем может быть неявно приведено к const void* путем встроенного преобразования. Поэтому эта функция вызывается этими аргументами и используется, так как другая не может быть выведена.

0 голосов
/ 08 февраля 2012

Используется неявное преобразование T в wchar_t.Любой тип может быть преобразован в void*, поэтому компилятор вызывает эту версию operator<<.Оператор T* никогда не был кандидатом, потому что не было никакого способа получить неявно T* от T.Вы хотели сделать его оператором T& <<?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...