Отключение функции, которая использует ограничение концепции, если концепция не соблюдается

Как я могу скомпилировать следующий код?

Я пытаюсь проверить, существует ли BigStruct в типе, и включить f, если это так.

#include <type_traits>
struct A {
    using BigStruct = int;
}; 

struct C {
};

template <typename T>
struct B {
    void f(typename T::BigStruct t) requires requires {T::BigStruct;} {}
};

int main() {
  B<A> b1;
  B<C> b2;
}

Ошибка, которую я получил:

<source>:11:24: error: no type named 'BigStruct' in 'C'
    void f(typename T::BigStruct t) requires requires {T::BigStruct;} {}
           ~~~~~~~~~~~~^~~~~~~~~
<source>:16:8: note: in instantiation of template class 'B<C>' requested here
  B<C> b2;
       ^
1 error generated.
ASM generation compiler returned: 1
<source>:11:24: error: no type named 'BigStruct' in 'C'
    void f(typename T::BigStruct t) requires requires {T::BigStruct;} {}
           ~~~~~~~~~~~~^~~~~~~~~
<source>:16:8: note: in instantiation of template class 'B<C>' requested here
  B<C> b2;
       ^
1 error generated.
Execution build compiler returned: 1

Вот ссылка на godbolt для x86-64 clang trunk.

Это специально, что B является шаблоном класса? Или, возможно, вы просто хотите, чтобы f был шаблоном функции?

463035818_is_not_a_number 10.01.2023 17:20

@ 463035818_is_not_a_number намеренно B является шаблоном класса.

weineng 10.01.2023 17:21

@ 463035818_is_not_a_number: Разумно предположить, что B содержит другие вещи. MCVE минимальны, поэтому они не являются исходным кодом.

Nicol Bolas 10.01.2023 17:29

@NicolBolas абсолютно разумно. Что касается концепций, которые я новичок, вопрос был чисто любопытным.

463035818_is_not_a_number 10.01.2023 17:32
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
3
4
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проверка понятий для функций, не являющихся шаблонами, происходит после создания подписи функции. Это означает, что список параметров должен существовать. И, следовательно, он должен быть синтаксически допустимым.

В этом случае вы мало что можете сделать, если не хотите ограничивать весь класс, кроме старой стратегии до C++20 превращения самой функции в шаблон:

template<typename U = T>
  requires requires {typename U::BigStruct;} 
void f(typename U::BigStruct t) {}

Есть ли польза от требований? Спрашиваю, потому что без godbolt.org/z/3nMne65Ee эффект тот же.

463035818_is_not_a_number 10.01.2023 17:33

@ 463035818_is_not_a_number: Это делает более понятным требование. SFINAE — это своего рода хак.

Nicol Bolas 10.01.2023 17:35

Другие вопросы по теме