如何将函数参数生成为具有模板参数中指定长度的序列

问题描述 投票:0回答:1

什么是通用化模板以将可变数量的参数(作为模板参数给出的计数)传递给函数的干净方法?例如函数

permute
,如下:

template<std::size_t N>
using byte_vector_t = uint8_t __attribute__((ext_vector_type(N)));

template <std::size_t N, int(*f)(int)>
byte_vector_t<N> permute(byte_vector_t<N> x, byte_vector_t<N> y) {
    return __builtin_shufflevector(x, y, f(0), f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9), f(10), f(11), f(12), f(13), f(14), f(15) );
}

template <std::size_t N>
byte_vector_t<N> zip_lo(byte_vector_t<N> x, byte_vector_t<N> y) {
    auto f = [](int i) -> int { return ((i & 1) ? N : 0) + (i / 2); };
    return permute<N, f>(x, y);
}

但这仅适用于 N=16:

// works
typedef uint8_t test16_t __attribute__((ext_vector_type(16)));
test16_t zip_lo16(test16_t x, test16_t y) {
    return zip_lo(x, y);
}

// does not work    
typedef uint8_t test8_t __attribute__((ext_vector_type(8)));
test8_t zip_lo8(test8_t& x, test8_t& y) {
    return zip_lo(x, y);
}

std::apply
似乎可能相关,但
__builtin_shufflevector
拒绝传递进去。即使它有效,我仍然不知道如何最好地生成元组。

c++ templates parameter-passing clang++
1个回答
1
投票

您应该能够使用

index_sequence
:

#include <utility>

template <std::size_t N, int (*f)(int)>
byte_vector_t<N> permute(byte_vector_t<N> x, byte_vector_t<N> y) {
    return [&]<std::size_t... I>(std::index_sequence<I...>) {
        return __builtin_shufflevector(x, y, f(I)...);
    }(std::make_index_sequence<N>());
}

演示


如果您使用 C++17,则无法使用通用 lambda,因此您需要一个辅助函数:

template <int (*f)(int), std::size_t... I>
byte_vector_t<sizeof...(I)> permute_helper(byte_vector_t<sizeof...(I)> x,
                                           byte_vector_t<sizeof...(I)> y,
                                           std::index_sequence<I...>) {
    return __builtin_shufflevector(x, y, f(I)...);
}

template <std::size_t N, int (*f)(int)>
byte_vector_t<N> permute(byte_vector_t<N> x, byte_vector_t<N> y) {
    return permute_helper<f>(x, y, std::make_index_sequence<N>());
}
© www.soinside.com 2019 - 2024. All rights reserved.