в С++ способ проверить внутри if-constexpr может ли некая шаблонная функция быть вызывана с аргументом определенного типа?
Я тут пытаюсь сделать через "if constexpr(requires { fn(obj); })" https://godbolt.org/z/8Ta78YTKG
#include <iostream>
struct Struct1 {
int field;
};
struct Struct2{
int field2;
};
auto obj1 = new Struct1{123};
auto obj2 = new Struct1{234};
auto fn1 = [](auto obj1){
std::cout << "fn1:" << obj1->field << "\n";
};
auto fn2 = [](auto obj2){
std::cout << "fn2:" << obj2->field2 << "\n";
};
auto invokeWithObj(auto obj, auto fn1, auto fn2){
if constexpr(requires{ fn1(obj); }){
fn1(obj);
}
if constexpr(requires{ fn2(obj); }){
fn2(obj);
}
};
int main(){
invokeWithObj(obj1, fn1, fn2);
invokeWithObj(obj2, fn1, fn2);
}
но это не работает и выдает ошибку "error: no member named field2 in Struct1"
То есть if constexpr + requires не срабатывает и компилятор продолжает инстанциирование для второй ветки с типом первого объекта
Существует сейчас ли в С++ способ заставить работать этот пример??? Если requires{ fn(obj); } не работает то может можно как-то через перегрузку (вроде есть еще всякие "detection idiom" подходы). Я хочу вызвать переданный объект либо с первой либо со второй лямбдой в зависимости от того можно ли ее вызвать/проинстанциировать с этим объектом
Инстанцирование fn1 с неверным типом - всегда hard error. Так что не меняя fn1 придумать ничего нельзя
std::is_invokable?
Не сработает
Действительно, работает только с нешаблонными функциями а с шаблонными не работает https://godbolt.org/z/a4Y48ePvo
жаль.. и никаких способов (включая самые безумные вроде лупхолов) до сих пор не придумали в С++ сообществе?
ну так примени концепты, с которыми играесся, по назначению — обмажь шаблонную requires'ами чтобы оно неправильные типы не пускало
к сожалению из-за отсуствия requires(auto) придется через макрос дублировать тело функции в внутри requires{}-концепта, но в принципе тоже идея
А зачем это? Вызови функцию. Вызовется - ок, код будет работать. Нет - будет работать другая специализация шаблона
посмотри эту демку https://godbolt.org/z/1KGeb7Gra там в примерах я часто использую макрос if_constexpr(...) чтобы не писать болерплейт а все потому что я не могу при матчинге проверить будет ли лямбда-коллбек вызываться с этим типом или нет
В ридми обман, получается, нельзя без __if_constexpr обойтись
не совсем, если скопировать тот пример без других примеров то он будет работать (необходимость использовать if-constexpr появляется когда происходит стирания многих несовместимых типов). Так что там не обман а не договоренность)
Обсуждают сегодня