170 похожих чатов

Народ, помогите пожалуйста с одним важным вопросом - есть ли

в С++ способ проверить внутри 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" подходы). Я хочу вызвать переданный объект либо с первой либо со второй лямбдой в зависимости от того можно ли ее вызвать/проинстанциировать с этим объектом

11 ответов

38 просмотров

Инстанцирование fn1 с неверным типом - всегда hard error. Так что не меняя fn1 придумать ничего нельзя

std::is_invokable?

Богдан- Автор вопроса
Alexander Karaev
Инстанцирование fn1 с неверным типом - всегда hard...

Действительно, работает только с нешаблонными функциями а с шаблонными не работает https://godbolt.org/z/a4Y48ePvo

Богдан- Автор вопроса
Alexander Karaev
Инстанцирование fn1 с неверным типом - всегда hard...

жаль.. и никаких способов (включая самые безумные вроде лупхолов) до сих пор не придумали в С++ сообществе?

Богдан
Действительно, работает только с нешаблонными функ...

ну так примени концепты, с которыми играесся, по назначению — обмажь шаблонную requires'ами чтобы оно неправильные типы не пускало

Богдан- Автор вопроса
Гражданин Котейко
ну так примени концепты, с которыми играесся, по н...

к сожалению из-за отсуствия requires(auto) придется через макрос дублировать тело функции в внутри requires{}-концепта, но в принципе тоже идея

А зачем это? Вызови функцию. Вызовется - ок, код будет работать. Нет - будет работать другая специализация шаблона

Богдан- Автор вопроса
Ilya Zviagin
А зачем это? Вызови функцию. Вызовется - ок, код...

посмотри эту демку https://godbolt.org/z/1KGeb7Gra там в примерах я часто использую макрос if_constexpr(...) чтобы не писать болерплейт а все потому что я не могу при матчинге проверить будет ли лямбда-коллбек вызываться с этим типом или нет

Богдан
посмотри эту демку https://godbolt.org/z/1KGeb7Gra...

В ридми обман, получается, нельзя без __if_constexpr обойтись

Богдан- Автор вопроса
Alexander Karaev
В ридми обман, получается, нельзя без __if_constex...

не совсем, если скопировать тот пример без других примеров то он будет работать (необходимость использовать if-constexpr появляется когда происходит стирания многих несовместимых типов). Так что там не обман а не договоренность)

Похожие вопросы

Обсуждают сегодня

Ребят в СИ можно реализовать ООП?
Николай
33
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем доброго вечера. Разрабатываю 32 раз. приложение в Delphi. Столкнулся с тем, что стандартный  TFilestream  не работает с большим файлом > 2 ГБайт (после вызова функции see...
Vadim Gl
16
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
добрый день. Подскажите, есть сайт на 1.4.7 и я хочу обновиться, особо ничего не меняя. мне выбирать версию 1.4.35 или третью ветку? и можно ли обновлять "как есть", или нужно...
Digital Cat
12
Кто кодит под Лазарем на винде, у вас аналогично VCL переопределяются CreateWnd и CreateParams для конкретных классов контролов и все заданные флаги влияют?
А Андрей
11
У меня задача: написать брокер сообщений. Очереди и потребители. Очереди поддерживают приоритеты. Очередь отдает сообщения, только обработчикам с соответствующими характеристи...
Aleksandr Filippov
2
народ, плиз хелп, всю голову сломал себе уже... разве может быть так, что GetProcAddress( GetModuleHandle( "kernel32.dll" ), "SetThreadDescription" ) вернёт ненулевое значение...
Iluha Companets
12
А, ты про текущую реализацию? Нет конечно, я бы сделал правильно - сейчас там гавнокод
Александр (Rouse_) Багель
6
Карта сайта