c++ - 在可变参数模板中实现 STL 函数

标签 c++ templates metaprogramming variadic-templates variadic-functions

我一直在做一个小项目来跟上可变参数模板的速度。我实现了一个小的多维数组。我现在想定义一个对给定位置的最近邻居进行操作的函数——是否有一种优雅的方法来检索数组中给定位置的邻居的值?

template<class T, size_t size, size_t... sizes>
struct MArr {
    typedef std::array<typename MArr<T, sizes...>::type, size> type;

    std::array<MArr<T, sizes...>,size> data;

    MArr<T, sizes...>& operator[](int i) {
        return data[i];
    }

};

template<class T, size_t size>
struct MArr<T, size> {
    typedef std::array<T, size> type;
    type data;

    T& operator[](int i) {
       return data[i];
    }

};

附录:我有点清楚如何通过使用递归来循环所有元素,例如将任意函数应用于 hyperdim。整数数组:

template <typename T, size_t size>
void func(MArr<T, size>& arr, std::function<void(int &)> f) {
    for (int i = 0; i < size; i++) {
       f(arr[i]);
    }
}


template <typename T, size_t size0, size_t size1, size_t ...sizes>
void func(MArr<T, size0, size1, sizes...>& arr, std::function<void(int &)> f) {
    for (int i =0; i < size0; i++) {
        func<T, size1, sizes...>(arr[i], f);
    }
}

我很好奇如何生成类似 func(arr[i+1,j,k,…],arr[i-1,j,k,…],arr[i,j+1 ,k,…],arr[i,j-1,k,…],…) 和给定的 func(比如添加相应的元素)。正如我所说,可变参数模板很新,我觉得我还没有正确的心态......

最佳答案

你可以这样做(代码使用来自 C++17 的折叠表达式,但可以用 C++11 编写):

template <std::size_t I, typename F, std::size_t ... Is, typename Tuple>
void helper(F&& f, std::index_sequence<Is...>, const Tuple& t)
{
    f((std::get<Is>(t) - (Is == I))...);
    f((std::get<Is>(t) + (Is == I))...);
}

template <typename F, std::size_t ... Is, typename Tuple>
void helper(F&& f, std::index_sequence<Is...> Seq, const Tuple& t)
{
    (helper<Is>(std::forward<F>(f), Seq, t), ...);
}

template <typename F, typename ... Ts>
void apply_to_neighboor(F&& f, Ts... indexes)
{
    helper(std::forward<F>(f), std::index_sequence_for<Ts...>(), std::tie(indexes...));
}

Demo

如果你想检索所有邻居,你可以将上面的代码更改为:

template <std::size_t I, std::size_t ... Is, typename Tuple>
auto helper1(std::index_sequence<Is...>, const Tuple& t)
{
    return std::make_pair(std::make_tuple((std::get<Is>(t) - (Is == I))...),
                          std::make_tuple((std::get<Is>(t) + (Is == I))...));
}

template <std::size_t ... Is, typename Tuple>
auto helper(std::index_sequence<Is...> Seq, const Tuple& t)
{
    return std::tuple_cat(helper1<Is>(Seq, t)...);
}

template <typename F, typename ... Ts>
void apply_to_neighboor(F&& f, Ts... indexes)
{
    std::apply(std::forward<F>(f),
               helper(std::index_sequence_for<Ts...>(), std::tie(indexes...)));
}

Demo

关于c++ - 在可变参数模板中实现 STL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47959900/

相关文章:

c++ - 为什么 std::is_invocable 不接受非类型模板参数

c++ - 模板类的友元模板函数

c++ - 我的程序中出现访问冲突(段错误)

c++ - 如何获取元组的一部分?

php - 使用正则表达式解析嵌套的 IF 语句

Ruby:来自散列的元编程方法

ruby - remove_const :File

c++ - 获取链接列表以打印数字

c++ - 应用商店应用中的 OpenSSL

c++ - 如何从C++中的文件读取字符数组(带有一些空间)