Ошибка вывода / замены аргумента шаблона при использовании аргумента typename

У меня есть следующий код, который определяет структуру шаблона W, которая экспортирует тип T, основанный на аргументе шаблона в W:

#include <iostream>
using namespace std;

template <unsigned N>
struct Y {};

template <unsigned N>
struct W {
  using T = Y<N>;
};

Затем я определил эту шаблонную функцию, которая смотрит на этот тип T:

template <unsigned N>
void foo (const typename W<N>::T& in) {
  //--
}

Проблема здесь в том, что если я попытаюсь вызвать эту функцию из main, используя один из типов, экспортированных как T, она не будет компилироваться. Например, если я напишу

int main() {
  Y<2> y;
  foo(y);
  return 0;
}

Я получаю сообщение об ошибке компилятора

Ошибка вывода / замены аргумента шаблона:

не удалось вывести параметр шаблона

Что тут происходит?


person Blaise Tine    schedule 05.11.2017    source источник


Ответы (1)


Причина, по которой компилятор C ++ не может этого понять, связана со специализацией шаблонов. Например, предположим, что вы специализируете шаблон структуры W следующим образом:

template <> struct W<137> {
    using T = Y<0>; // Not Y<137>
};

Теперь предположим, что вы вызываете foo, передавая Y<0> в качестве аргумента. Что компилятор должен вывести как числовое значение N? Это может быть ноль, поскольку W<0> определяет T как Y<0>. Но с таким же успехом это могло быть и 137, поскольку W<137> также определяет T как Y<0>.

В более общем плане C ++ никогда не будет пытаться определить тип аргумента шаблона для внешнего шаблона на основе одного из внутренних типов именно по указанной выше причине.

person templatetypedef    schedule 05.11.2017