有没有办法获得给定数量的输入,其中数字是在c ++的编译时由模板给出的?

use*_*164 9 c++ templates

例如,假设我创建了如下所示的类:

template <unsigned int INPUT_SIZE>
class A{
public:
    int operator()(int input, ...){ // get INPUT_SIZE-many inputs
        // return sum;
    }
};
Run Code Online (Sandbox Code Playgroud)

我想获得与INPUT_SIZE一样多的输入,而不是更多或更少.我怎样才能做到这一点?

另外,我使用的是c ++ 11,但如果在c ++ 14或更高版本中有更好的方法,我也想知道.

Jan*_*ans 14

Live demo 1

template <class T, auto> using always_t = T;

template <class T, class Arity>
struct A_impl;

template <class T, std::size_t... Is>
struct A_impl<T, std::index_sequence<Is...>>
{
    int operator ()(always_t<T, Is>...)
    {
        return 0;
    }
};
template <std::size_t N>
struct A : A_impl<int, std::make_index_sequence<N>>
{ };


A<2>{}(1, 2); // fine
A<2>{}(1, 2, 3); // fail
Run Code Online (Sandbox Code Playgroud)

这是一个允许您计算参数总和的版本:

Live demo 2

template <class T, auto> using always_t = T;

template <class T, class Arity>
struct A_impl;

template <class T, std::size_t... Is>
struct A_impl<T, std::index_sequence<Is...>>
{
    constexpr int operator ()(std::tuple<always_t<T, Is>...>&& t) {
        auto adder = [](auto... ts) {
            return (0 + ... + ts);
        };
        return std::apply(adder, std::move(t));
    }
};

template <std::size_t N>
struct A : A_impl<int, std::make_index_sequence<N>>{
};

constexpr int sum = A<3>{}({1, 4, 5});
static_assert(sum == 10);
Run Code Online (Sandbox Code Playgroud)

诀窍是使用带有长度的参数包,N以便我们可以使用它将N特定类型的扩展扩展到参数列表中A_impl::operator().

参数包可以扩展为N(通常)前面的模式的重复...


考虑一下这样的函数:

template<class... T>
void foo(T...);
Run Code Online (Sandbox Code Playgroud)

T...用简单的术语表示它可以被连续的类型替换成参数列表foo,一个可能的扩展可能是foo(int, int, double, char),也注意到什么...是来自的标识符class... T.


回到代码,我们需要生成一个参数包,我们通过std::make_index_sequence<N>生成,生成0..(N-1)捕获的序列std::size_t... Is,然后我们使用这个包来扩展always_t<T, Is>只是别名的模式T=int,这最终重复T=int多次作为元素Is包含.

注意:省略号参数...与参数包不同.