Играю с Concepts 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;
// ...
};
(Примечание: помимо конкретного вопроса, я также приветствовал бы обсуждение (в комментариях, конечно) аспектов дизайна Concepts TS, которые имеют отношение к этому вопросу, и / или решений, которые предлагают люди, поскольку часть Причина, по которой я играю с Concepts TS, состоит в том, чтобы увидеть, насколько хорошо он работает на практике, чтобы увидеть, есть ли какие-либо полезные отзывы для комитета до полной стандартизации. Например, есть ли настройка в дизайне "Concepts Lite", которая могла бы убрать необходимость дублировать такие requires
предложения?)
VectorSpecialization_CV
, но в другом месте упоминается какVectorSpecialization
, (2) определение ODR-используетstd::declval
, что является недопустимым. - person Casey   schedule 02.12.2016std::declval
- нет-нет? Он компилировался для меня, но это потому, что я еще не создавал экземпляр шаблона функцииdot
; как только я добавил код для этого, компилятор (GCC) сообщил мнеerror: call to non-constexpr function
, имея в видуstd::declval<VectorCandidate>()
, на который вы указали. Я достаточно хорошо понимаю эту ошибку. Но есть ли что-то большее, чем то, о чем вы говорили? - person Anthony Hall   schedule 03.12.2016declval
([declval] / 2), поскольку реализации только декларируют это. Использование ODR вconstexpr
контексте неправильно по двум причинам. - person Casey   schedule 03.12.2016