Я не понимаю почему в консоль печатается лишь «f::tick_2»? Ождилаось «f::tick_1 f::tick_2». Так ведут себя Шланг, ГЦЦ, и Мелкомягий.
#include <iostream>
using namespace std;
template <typename T, int I>
struct Ev {
struct DD {
};
template <typename ...Fn>
struct Ovl : Fn... {
using Fn::operator()...;
};
template<typename ...Fn> Ovl(Fn...) -> Ovl<Fn...>;
};
template <typename T, int I, typename V>
struct Tb {
V v;
};
template <typename T, int I, typename V>
void f(Tb<T, I, V> &tb) {
if (requires {tb.v(declval<Ev<T, I>::DD>());}) // #1
cout << "f::tick_1\n";
if (requires (typename Ev<T, I>::DD d){tb.v(d);}) // #2
cout << "f::tick_2\n";
}
int main() {
Ev<char, 3>::Ovl ovl{
[](Ev<char, 3>::DD) {return 1;}
};
Tb<char, 3, decltype(ovl)> tb{ovl};
f(tb);
}
$ g++ -std=c++20 1.cpp
$ ./a.out
f::tick_2
Разница лишь в способе «создания» DD в f::if. Тут немного запутанно, повторил примерно рабочую структуру с существующего кода, с менее хитрыми типами «ошбка» может не проявиться. В коде можно не разбираться сильно, интересна лишь строка #1 и #2. Единодушие компиляторов вызывает сомнение, что мои ожидания имеют основания.