gpt4 book ai didi

c++ - 如何获得可调用类型的签名?

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:55 25 4
gpt4 key购买 nike

我想构建一个漂亮的现代界面来构建计算树,如下所示:

auto [F, G] = calcs.emplace(
[](int a, int b){ return a + b; },
[](){ return 4; }
);

我的灵感来自taskflow , 但在这里我们也可能添加参数和返回类型,问题来了:我们如何推断给定 Callable 对象的底层存储类型,以及如何将它们存储在集合中?是否有可能创建具有当前语言特性的如此简单的 api?

我在谷歌上搜索了几个小时,看起来返回类型是一个较小的问题,但我对参数一无所知。

最佳答案

问:如何获得签名?

A: 通过 operator() 上的模式匹配可调用的方法,例如:

template <class TMethodType>
struct ReadSignature;

// Const specialization
template <class TReturnType, class TClass, class ... TArgsTypes>
struct ReadSignature<TReturnType(TClass::*)(TArgsTypes...) const> {
using ReturnType = TReturnType;
using Class = TClass;
using Args = std::tuple<TArgsTypes...>;

static constexpr bool is_const = true;
};

// Non-const specialization
// This is for mutable lambdas, e.g. []() mutable {}
template <class TReturnType, class TClass, class ... TArgsTypes>
struct ReadSignature<TReturnType(TClass::*)(TArgsTypes...)> {
using ReturnType = TReturnType;
using Class = TClass;
using Args = std::tuple<TArgsTypes...>;

static constexpr bool is_const = false;
};

你可以这样使用它:

    auto callable = [](int x, int y) { return x + y; };
using Class = decltype(callable);
using Signature = ReadSignature<decltype(&Class::operator())>;

问:如何在集合中存储可调用对象?

答:您需要以某种方式删除类型。对于可调用对象,制作包装器接口(interface)似乎很自然。例如,像这样:

class CallableI {
virtual ~CallableI() = default;

virtual std::any call(const std::vector<std::any>& args) = 0;

// For type checking:
virtual size_t arg_count() = 0;
virtual std::type_info get_arg_type_info(size_t arg_index) = 0;
virtual std::type_info get_return_type_info() = 0;
};

然后您编写一个实现此接口(interface)的模板类,该接口(interface)将为每个 lambda 参数实例化。在你的calcs您实际存储的对象 std::vector<std::unique_ptr<CallableI>> .

关于c++ - 如何获得可调用类型的签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54713870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com