Я играю с концепциями TS в новом проекте. Мой вопрос связан с кажущейся круговой зависимостью между шаблоном структуры и связанной с ней концепцией, которую я хочу создать. Конкретная логика концепции заключается в проверке того, что аргумент типа для концепции является специализацией шаблона структуры. Поскольку я хотел бы, чтобы концепция была доступна для использования внутри шаблона структуры, мне, видимо, необходимо определить концепцию до шаблона структуры, но тогда логика концепции должна также знать о шаблоне структуры. Я разработал что-то, что скомпилирует, переместив , объявив шаблоном структуры Vector
, затем определив концепцию VectorSpecialization
, а затем , определяющий шаблон структуры Vector
. Мой конкретный вопрос связан с тем, что я использую предложение requires
для шаблона структуры; когда я его объявляю, компилятор дает мне ошибку, если я не дублирую полное предложение requires
. (См. Код ниже).Избегайте дублирования запроса в форвардном объявлении шаблона?
Моего конкретный вопрос является: есть способ избежать полного дублирования requires
пункта между упреждающим объявлением шаблоном и определением? Одна из возможностей заключалась бы в том, чтобы исключить логику предложения requires
в общую сущность, которую могут делегировать как декларация, так и определение, что, я полагаю, будет касаться принципа DRY; но мне любопытно, есть ли структурное решение более высокого уровня, которое я мог бы сделать здесь, чтобы избежать необходимости даже иметь предложение requires
в обоих местах, или если есть более идиоматический способ использования концепций для подобных случаев, которые я мог бы использовать выгода от. Чтобы повторить итерацию, я использую этот вариант: написать концепцию, которая будет использоваться в шаблоне, но концепция также должна знать о шаблоне.
// Forward declare the struct template so that the concept can refer to it
// Note the need to repeat the 'requires' clause. Can that repetition be
// be avoided?
template< typename T, size_t N > requires N > 1 struct Vector;
// compile-time overload set using template arg deduction to detect
// when the argument is a specialization of 'Vector'
template< typename NonVector >
constexpr bool IsVectorSpecialization(NonVector &&) {
return false;
}
template< typename T, size_t N >
constexpr bool IsVectorSpecialization(Vector<T, N> &&) {
return true;
}
// The concept, which uses the above overloaded constexpr function
template< typename VectorCandidate >
concept bool VectorSpecialization_CV
= IsVectorSpecialization(std::declval<VectorCandidate>());
template< typename T, size_t N >
requires N > 1
struct Vector : std::array<T, N> {
// Some function templates with VectorSpecialization parameters, e.g.
// T dot(VectorSpecialization const &other) const;
// ...
};
(Примечание: Помимо конкретного вопроса, я бы также приветствовать обсуждение (в комментариях, конечно) об аспектах дизайна Концепции TS, которые имеют по этому вопросу и/или решений, которые предлагают людям , так как часть причины, по которой я играю с концепцией TS, - это увидеть, насколько хорошо она работает на практике, чтобы увидеть, есть ли какая-нибудь полезная обратная связь для комитета до полной стандартизации. Например, есть ли настройка дизайна " Concepts Lite ", который мог бы устранить необходимость дублирования requires
таких статей?)
Есть пара проблем с образцом кода: (1) концепция называется 'VectorSpecialization_CV', но в другом месте называется« VectorSpecialization », (2) определение ODR - использует' std :: declval', что нет-нет. – Casey
@ Casey, не могли бы вы рассказать о том, что 'std :: declval' является no-no? Он компилировался для меня, но это потому, что я еще не создавал шаблон функции «точка»; как только я добавил код для этого, компилятор (GCC) сказал мне «error: call to non-constexpr function», ссылаясь на 'std :: declval()', на который вы указали. Я достаточно хорошо понимаю эту ошибку. Но есть ли что-то еще для этого, о чем вы говорили? –
Это достаточно близко;) Стандарт явно запрещает ODR-использование 'declval' ([declval]/2), поскольку реализации только объявляют его. Использование ODR в контексте 'constexpr' плохо организовано по двум причинам. – Casey