循环 typedef 列表

Loop a list of typedefs

如果标题有点误导,我很抱歉。

我有一个循环一些数据的函数。每次迭代都会更改此数据的类型。

基本上我有这样的东西:

for(int i = 0; i < limit; i++)
{
  type object;
  object.do_stuff();
}

例如,在第一次迭代中 "type" 将是 int,在第二次迭代中 "type" 将是 double,等等

我不能使用 varyadic 模板,因为我有超过 100 个元素,据我所知,这对系统来说会很费力。

我的想法是创建一个 "vector of typedefs" 来循环 objects 的所有类型。

vector<????> type;
type.push_back(int);
type.push_back(double);
...
for(int i = 0; i < limit; i++)
{
  type[i] object;
  object.do_stuff();
}

我不知道这是否可行。

我看到了类型列表的基础知识,但我不知道是否可以重现循环。

I can't use varyadic templates because i have more than 100 elements and from what i know it will be very taxing for the system.

您所知道的不是过时就是不准确。只需查看 metaben.ch 即可了解在对编译时间影响最小的情况下可以得到多大的类型列表。


My idea was to create a "vector of typedefs" to cycle all the types of the objects.

那是一个打字列表。您可以执行以下操作:

// Store the type in a value for convenience
template <typename T>
struct type_wrapper
{
    using type = T;
};

template <typename... Ts>
struct typelist
{
    template <typename F>
    constexpr void for_each(F&& f)
    {
        // C++17 fold expression over comma operator
        (f(type_wrapper<Ts>{}), ...);
    }
};

C++17 用法:

typelist<int, float, char>{}.for_each([](auto t)
{
    using type = typename decltype(t)::type;
    // Use `type`
});

C++20 用法(对 typelist 进行了细微更改):

template <typename... Ts>
struct typelist
{
    template <typename F>
    constexpr void for_each(F&& f)
    {
        // C++17 fold expression over comma operator
        (f.template operator()<Ts>(), ...);
    }
};

typelist<int, float, char>{}.for_each([]<typename T>()
{
    // Use `T`
});

我写了一篇与这个主题相关的短文:"compile-time iteration with C++20 lambdas ".

我们可以用稍微不同的方式来看待这个问题,然后说您可能真正想要的是一个向量(或者,我可能更愿意说,列表)事物do,这可以通过 中的一些工具以非常通用的方式实现。一起来看看:

#include <vector>
#include <functional>
#include <iostream>

static void process_int (int i) { std::cout << "process_int " << i << "\n"; }
static void process_string (std::string s) { std::cout << "process_string " << s << "\n"; }
// ...                                            

int main()
{
    std::vector <std::function <void ()>> v;

    v.push_back (std::bind (process_int, 42));
    v.push_back (std::bind (process_string, "Hello world"));

    for (auto f : v)
        f ();                    
}

输出:

process_int 42
process_string Hello world

它再简单不过了,不是吗,您可以通过各种聪明(或不太聪明)的方式对其进行调整,以适应您的特定用例。正如现场演示所示,在 C++11 中应该没问题。您还可以将 lambda 传递给 std::bind.

Live demo.