Вопрос: Параметр шаблона шаблона и значения по умолчанию [duplicate]


На этот вопрос уже есть ответ:

Рассмотрим следующий код:

template<typename T>
struct A { };

// same as A, but with one extra defaulted parameter
template<typename T, typename F = int>
struct B { };

template<template<typename> typename T>
T<int> build() { return {}; }

int main()
{
    build<A>();  // works in gcc and clang
    build<B>();  // works in gcc, does not work in clang
}

g ++ (7.3.0) компилирует код просто отлично, однако clang ++ (5.0.1) испускает следующее:

example.cpp:14:5: error: no matching function for call to 'build'
    build<B>();  // works in gcc, does not work in clang
    ^~~~~~~~
example.cpp:9:8: note: candidate template ignored: invalid
      explicitly-specified argument for template parameter 'T'
T<int> build() { return {}; }

Какой из компиляторов прав?


Заметка: Важная строка, очевидно:

template<template<typename> typename T>

Поскольку оба компилятора удовлетворяются:

template<template<typename...> typename T>

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


11


источник


Ответы:


Насколько я знаю, ваш код верен, начиная с C ++ 17, раньше.

Это соответствует P0522R0 , который является частью нового стандарта, где я вижу пример, который очень, очень похож на ваш код (см. «обзор»):

template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>();  // OK; error before this paper (CWG 150)

Согласно таблицы поддержки компилятора в ccpreference , g ++ поддержка P0522R0 из версии 7, clang ++ из версии 4. Таким образом, оба компилятора должны поддерживать ваш код.

Но глядя в таблицу в эта страница , поддержка llvm (clang) 5 определяется как «частичная» и, согласно примечанию,

(12): Несмотря на то, что это разрешение отчета об ошибках, эта функция отключена по умолчанию во всех языковых версиях и может быть включена явно с флагом -frelaxed-template-template-args в Clang 4 и далее. Изменение стандарта не соответствует соответствующему изменению для частичного упорядочения шаблонов, что приводит к ошибкам неоднозначности для разумного и ранее действующего кода. Ожидается, что этот вопрос будет исправлен в ближайшее время.

Таким образом, на ваш риск, вы можете попробовать с флагом -frelaxed-template-template-args,


6