Подтвердить что ты не робот

Вывод типа аргумента шаблона оператором преобразования

Я вижу пример из С++ 11 Standard (n3337, 14.8.2.3/7)

struct A {
template <class T> operator T***();
};
A a;
const int * const * const * p1 = a; // T is deduced as int, not const int

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

struct A {
    template <class T> operator T***()
    {
        T t;  //if T==const int, then it is error (uninitialized const)
        return nullptr;
    }
};
A a;
const int * const * const * p1 = a;

int main(){}

Все компиляторы (VS2014, gcc 5.1.0 и clang 3.5.1) дают ошибку в объявлении "t", что означает, что T выводится как const int. Почему это? Это расширение?

4b9b3361

Ответ 1

Это было описано проблема CWG № 349, открытая разработчиком EDG С++ front end (который, по-видимому, выводит int, а не const int):

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

Возникает вопрос: каков тип T в функциях преобразования вызванный этим примером? Является ли T "int" или "const int"?

Если T является "int", функция преобразования в классе A работает, а функция класс B не работает (потому что выражение возврата не может быть преобразовано в возвращаемый тип функции). Если T является "const int", A терпит неудачу и B работы.

Поскольку преобразование квалификации выполняется по результату преобразования, я не вижу преимущества при выводе T как const int.

Кроме того, я думаю, что код в классе A будет более вероятным, чем код в классе B. Если автор класса планировал возвращая указатель на объект const, я ожидал бы, что функция будет были записаны с константой в возвращаемом типе.

Следовательно, я считаю, что правильным результатом должно быть то, что T является int.

struct A {
  template <class T> operator T***() {
      int*** p = 0;
      return p;
  }
};

struct B {
  template <class T> operator T***() {
      const int*** p = 0;
      return p;
  }
};

int main()
{
  A a;
  const int * const * const * p1 = a;
  B b;
  const int * const * const * p2 = b;
}

Мы только что реализовали эту функцию, и в ожидании разъяснения комитета, мы выводим T как int. Похоже, что g++ и компилятор Sun выводят T как const int.

Это привело только к появлению цитируемого абзаца (его не было в С++ 03!) и, по-видимому, он был упущен разработчиками компилятора.