Предположим, я хочу написать:
template<class T> concept WithNestedTemplate = ...;
struct F { template<class> using nested = int; };
static_assert(WithNestedTemplate<F>);
static_assert(!WithNestedTemplate<int>);
То есть WithNestedTemplate
должен проверить наличие T::template nested
шаблона класса члена или шаблона псевдонима с подписью template<class> class
.
Я могу написать вспомогательную концепцию:
template<template<class> class> concept TemplateOfᐸclassᐳ = true;
template<class T> concept WithNestedTemplate = TemplateOfᐸclassᐳ<T::template nested>;
Но это дает ложные срабатывания в gcc (например, концепция ошибочно принимает int
), сложно дать концепту-помощнику разумное имя, и теперь его определение потенциально находится далеко от того места, где оно используется.
Или я могу написать общую лямбду с помощью tparams:
template<class T> concept WithNestedTemplate = requires {
[]<template<class> class>(){}.template operator()<T::template nested>(); };
Но в настоящее время это не работает в clang (ему не нравятся лямбды в неоцененном контексте), ужасно уродливо и, возможно, непонятно для читателя.
Есть ли лучший способ сделать это - желательно тот, который работает во всех основных компиляторах?
Я должен, вероятно, упомянуть, что создание экземпляра T::template nested
в качестве теста не будет работать, поскольку его ограничение будет законным.