Вывод аргумента шаблона класса для типа шаблона, который сам является аргументом для шаблона - PullRequest
4 голосов
/ 11 октября 2019

Поддерживается ли вывод аргумента шаблона класса для типов шаблона с аргументами по умолчанию, которые используются в другом объявлении типа шаблона? Следующий код не компилируется с обоими стволами Clang / GCC, он завершается с ошибкой в ​​строке, определяющей y:

#include <optional>

template <class T = char>
struct C {};

int main() {
    C x;
    std::optional<C> y;
}

(https://godbolt.org/z/SgxY90)

Изменение кода для чтения std::optional<C<>> yустраняет проблему, но я немного удивлен, что это необходимо. Это проблема компилятора или известное ограничение языка?

1 Ответ

5 голосов
/ 11 октября 2019

Компилятор должен проверить, что то, что передается в шаблон, соответствует ожидаемому параметру шаблона. Теперь подумайте, я должен был написать это на вашем примере, где вы не видите foo:

foo<C> f;

Это экземпляр CTAD или я передаю сам шаблон? Поскольку уже можно передавать шаблоны в качестве аргументов другим шаблонам.

template< template<typename> class T > struct foo {};

Если в этом контексте разрешить использование CTAD, то использование C будет зависеть от контекста. Напротив, имя шаблона не имеет другого использования при объявлении переменной. Нет никакой двусмысленности при написании ...

C c;

... это может означать что-то отличное от CTAD, поэтому здесь это разрешено. Но контекст имеет значение, когда имя шаблона используется в качестве аргумента шаблона. В C ++ уже есть много контекстно-зависимых конструкций, поэтому добавление большего количества обычно плохая идея.

...