Фон
В соответствии со стандартом C ++ при прямом объявлении типа шаблона с параметрами шаблона по умолчанию каждый из них может появляться только в объявлении one .Например:
// GOOD example
template <class T = void>
class Example; // forward-declaration
template <class T>
class Example {}; // definition
// GOOD example
template <class T>
class Example; // forward-declaration
template <class T = void>
class Example {}; // definition
// BAD example
template <class T = void>
class Example; // forward-declaration
template <class T = void> // ERROR: template parameter redefines default argument
class Example {}; // definition
Проблема
В моем коде много предварительных объявлений в разных файлах, поэтому имеет смысл поместить параметры по умолчанию вопределение:
// foo.hpp, bar.hpp, baz.hpp, etc.
template <class T>
class Example;
// example.hpp
template <class T = void>
class Example {};
и, как и ожидалось, все работает хорошо везде ... кроме лязга!Я сузил проблему до следующего:
В clang, если шаблон класса имеет параметры по умолчанию, но они не объявлены в первом прямом объявлении этого класса и при объявлении экземпляра этого класса угловые скобки не указаны , clang игнорирует параметр по умолчанию и выдает ошибку «нет жизнеспособного конструктора или руководство по выводу для аргументов шаблона ...».
Пример
// GOOD example
template <class T>
class Example;
template <class T = void>
class Example {};
int main() {
Example e; // error: no viable constructor or deduction guide for deduction of template arguments of 'Example'
}
- Перемещение
= void
в предварительную декларацию решает проблему, но для меня это нецелесообразно, так как мои forward-decls находятся в разных файлах, и я не знаю, какой из них появится первым.(Также очень проблематично, так как мои значения по умолчанию будут в каком-то непонятном файле в глубине кодовой базы) - Изменение
Example e;
на Example<> e;
устраняет проблему, но не жизнеспособно для меня, так как я являюсь разработчиком библиотеки ия не хочу, чтобы все мои пользователи набирали <>
после моих занятий. - Добавление файла прямого объявления
example_fwd.hpp
с одним предварительным объявлением и включение его вместо прямого объявления каждый раз, когда исправляет проблему, но яЯ хотел бы избежать этого, если есть лучшее решение.
Вопрос
Кто прав в этом случае: clang или другие компиляторы?Это ошибка компилятора?Как я могу обойти эту проблему (кроме частичных решений, которые я описал выше)?Я нашел # 10147 (и связанные с ним вопросы stackoverflow), но он касается параметров шаблона шаблона и также помечен как исправленный более года назад.
Edit
Thisвыглядит как ошибка, и теперь сообщается об отслеживателе ошибок LLVM ( # 40488 ).