Почему зависимые типы шаблонов не выводятся при частичной специализации? - PullRequest
1 голос
/ 01 февраля 2020

При использовании clang 7.0.0 при компиляции этого кода появляются следующие ошибки:

template <typename A> class Outer
{
public:
    template <typename B> class Inner
    {
    };
};

template<typename C> struct Foo
{
};

template <typename D, typename E> struct Foo<typename Outer<D>::template Inner<E>>
{
};
 clang++-7 -pthread -std=c++11 -o main main.cpp
main.cpp:15:42: error: class template partial specialization contains template parameters that cannot be
      deduced; this partial specialization will never be used [-Wunusable-partial-specialization]
template <typename D, typename E> struct Foo<typename Outer<D>::template Inner<E>>
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:15:20: note: non-deducible template parameter 'D'
template <typename D, typename E> struct Foo<typename Outer<D>::template Inner<E>>
                   ^
main.cpp:15:32: note: non-deducible template parameter 'E'
template <typename D, typename E> struct Foo<typename Outer<D>::template Inner<E>>
                               ^

MSV C предлагает похожую ошибку.

Почему D и E франшиза?

Ответы [ 2 ]

4 голосов
/ 01 февраля 2020

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

Кроме того, если часть квалифицированного имени типа является не выводимым контекстом, то все параметры, используемые для указания типа, не выводятся.

Таким образом, в вашем примере ни D, ни E не выводятся из typename Outer<D>::template Inner<E>, и, поскольку нет другого способа вывести их, вывод не выполняется, что означает, что частичная специализация никогда не бывает жизнеспособной.

1 голос
/ 01 февраля 2020
Foo<Outer<int>::template Inner<int> > ...

Компиляторы C ++ не выводят при первом проходе, вы должны сказать ему, что обрабатываете контекстно-зависимый символ поиска вручную;

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