LINUX.ORG.RU

Код не отрабатывает как ожидается

 


0

2

Я не понимаю почему в консоль печатается лишь «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. Единодушие компиляторов вызывает сомнение, что мои ожидания имеют основания.

★★

Последнее исправление: kvpfs (всего исправлений: 1)

Ответ на: комментарий от utf8nowhere

Оно, спасибо. Какие-то грабли на ровном месте подкинули, что же ещё могу передать в параметр-тип шаблона? Без предупреждений, просто не работает и всё, думай что хочешь потом.

kvpfs ★★
() автор топика
Ответ на: комментарий от utf8nowhere

Это да, но я имею в виду предупреждения компилятора, он же видит, что declval специализируентся названием типа. Хотя подозреваю, что это попадает под SFINAE. Будет уроком, что лишних typename не бывает. Да ещё в голове крутится, что расслабляли требования по наличию typename в некоторых местах, особенно заметно по ГЦЦ в сравнении со шлангом.

kvpfs ★★
() автор топика