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

Дедуцирование аргументов шаблона класса с помощью конструктора, который использует псевдоним типа члена

Поэтому, по-видимому, это должно работать:

template<class T>
struct C {
   using value_type = T;
   C(value_type);
};

C c(1); // C<int>

Как это (см. пример B в [over.match.class.deduct]/3):

template<class T>
struct D {
   template<class> using meow_t = T;

   template<class U>
   D(U, meow_t<U>);
};

D d(1, 'c'); // D<char>

Обратите внимание, что явно эквивалентное явное руководство не будет работать, поскольку параметр является не выводимым контекстом:

template<class T>
C(typename C<T>::value_type) -> C<T>;

Несмотря на то, что желательно, чтобы по крайней мере первый фрагмент работал, мне еще не удалось найти формулировку, которая фактически заставляет ее работать в текущем рабочем проекте. Кто-нибудь знает, где это?

4b9b3361

Ответ 1

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


Это Основной вопрос 2. Дискуссия в Oulu и Issaquah об этой функции дала понять, что намерение заключается в том, что просмотр typedefs действительно, но никаких формулировок не добавлено, чтобы указать, как это должно работать - это просто... есть. Формулировка as-is предполагает, что руководство по вычету для:

template<class T>
struct C {
   using value_type = T;
   C(value_type);
};

:

template <class T> C<T> foo(typename C<T>::value_type );

который был бы не выводимым контекстом и потерпел неудачу, но [thread.lock.guard] не имеет явного руководства по вычитанию для Это дело.

Пример в [over.match.best], по-видимому, предназначен для указания того, что typedef должны работать, хотя ни один из примеров в этом примере фактически используют # 1 в качестве руководства для вычитания:

template <class T> struct A {
  using value_type = T;
  A(value_type);    // #1
  A(const A&);      // #2
  A(T, T, int);     // #3
  template<class U>
    A(int, T, U);   // #4
  // #5 is the copy deduction candidate, A(A)
};

A x(1, 2, 3);       // uses #3, generated from a non-template constructor

template <class T>
A(T) -> A<T>;       // #6, less specialized than #5

A a(42);            // uses #6 to deduce A<int> and #1 to initialize
A b = a;            // uses #5 to deduce A<int> and #2 to initialize

template <class T>
A(A<T>) -> A<A<T>>; // #7, as specialized as #5

A b2 = a;           // uses #7 to deduce A<A<int>> and #1 to initialize

Ответ 2

Я думаю, что тщательное прочтение делает это ясно:

Типы параметров функции - это параметры конструктора.

Обратите внимание, что C<T>::value_type не является типом, это имя typedef. Из-за подстановки тип параметра конструктора T, и эквивалентное руководство по вычитанию на самом деле

template <class T> C(T) -> C<T>;

В вашем примере использование C<T>::value_type показало, что ему понравилась проблема с не выводимым контекстом, но эта проблема на самом деле не существует, потому что для параметров функции дедукции нет никакого поиска.