gpt4 book ai didi

c++ - 编译时循环遍历模板化类型

转载 作者:太空宇宙 更新时间:2023-11-04 11:27:41 24 4
gpt4 key购买 nike

我一直在搜索 SO 和其他论坛,寻找一种方法来确定 lambda 的参数和返回类型,然后对这些参数进行操作,以便对已经存在的对象的 repo 进行类型查找实例化。重点是创建一种方法来对一些任意定义的 lambda 表达式进行依赖注入(inject)。例如,如果我有如下内容:

auto lambda = [] (MyObject o) -> string { return o.name(); };

我可以确定 lambda 的参数类型,并查找类型为 MyObject 的相应对象,然后调用 lambda“自动”传递该对象。

到目前为止,我已经找到了使用以下模板确定 lambdas 参数列表类型和返回类型的方法:

template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.

typedef ReturnType result_type;

template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};

我在 this 中找到的所以发布(非常整洁)。

现在,我想做的是实现某种编译时等效于以下内容:

// first get the type of the lambda using the above 'function_traits' template
typedef function_traits<decltype(lambda)> traits;
// now iterate over the traits and get the type of each argument, then print out the type name
for (size_t i = 0u; i < size_t(traits::arity); ++i)
{
// The point to focus on here is `traits::args<i>::type`
std::cout << typeid(traits::args<i>::type).name() << std::end;
}

我在上面发布的内容是不可能的。上面代码中的问题是 i 不是常量,而是在运行时求值,而不是编译时(在编译时求值模板魔法的其余部分)。我已经尝试了几种不同的方法来尝试找出解决此问题的方法(其中的模板递归),但我一直无法找到完全符合我要求的解决方案。

所以,我的问题的根源实际上是,您如何“迭代”模板?我是 TMP 的新手,从运行时逻辑到编译时逻辑的思维转变一直具有挑战性。如果有人对新手有一些建议,那就太好了。

最佳答案

使用 C++14,您可以:

namespace detail
{
template <typename T, std::size_t ... Is>
void display(std::index_sequence<Is...>)
{
std::initializer_list<int>{((std::cout << typeid(typename T::template arg<Is>::type).name() << std::endl), 0)...};
}

}

template <typename T>
void display()
{
detail::display<T>(std::make_index_sequence<T::arity>());
}

并使用它:

using traits = function_traits<decltype(lambda)>;

display<traits>();

Live example

如果您坚持使用 C++11,可以在很多地方找到 make_index_sequenceindex_sequence 的实现

关于c++ - 编译时循环遍历模板化类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26046913/

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