如何创建一个接受可变数量的 int 的 C++ 构造函数

How can I create a C++ constructor that accepts a variable number of int's

是否可以在可变参数构造函数中限制参数类型?

我想表达

X x1(1,3,4);
X x2(3,4,5);

// syntax error: identifier 'Args'
class X {
template<int ... Args> X(Args...)
{
}
};
// this works but allows other types than int
class Y {
template<typename ... Args> Y(Args...)
{
}
};

编辑以阐明意图:

我想要实现的是将传递给构造函数的数据(编译时已知的常量)存储到静态数组中。

所以还有一些其他的

template<int ...values>
struct Z
{
    static int data[sizeof...(values)];
};

template<int ... values>
int Z<values...>::data[sizeof...(values)] = {values...};

在 X 的构造函数中,我想像这样使用 Z:

class X {
    template<int ... Args> X(Args...)
    {
        Z<Args...>::data // do stuff with data
    }
};

这可能吗,我必须使用integer_sequence吗?

不,您不能限制类型。不过,您可以使用 static_assert。会是这样的:

static_assert(std::is_same<int, Args>::value ..., "have to be ints.");

虽然没有尝试在 static_assert 中使用扩展。您可能需要一个 returns bool 或其他东西的 constexpr。

因为你有:

template<int... values>
struct Z
{
    static int data[ sizeof...( values ) ];
};

template <int... values>
int Z<values...>::data[ sizeof...( values ) ] = { values... };

您可以使用 std::integer_sequence<> 将整数传递给 Z<>:

struct X
{
    template <int... values>
    X( std::integer_sequence<int, values...> )
    {
        for ( int i{ 0 }; i < sizeof...( values ); ++i )
            Z<values...>::data[ i ]; // do stuff with data
    }
};

你可以让自己成为一个助手类型,以便于调用ctor:

template <int... values>
using int_sequence = std::integer_sequence<int, values...>;

然后你可以像这样实例化你的class:

int main()
{
    X x( int_sequence<1, 3, 5>{} );
}

您可以使用 std::initializer_list:

#include <iostream>
#include <initializer_list>

void myFunc(std::initializer_list<int> args)
{
    for (int i: args) std::cout << i << '\n';
}
int main(){

    myFunc({2,3,2});
    // myFunc({2,"aaa",2}); error!

}

您已更新您的问题以表明您所需要的只是一个编译时std::integer_sequence,这很好。

但为了未来可能会来这里寻找答案的读者,我也想回答你原来的问题 "Is it possible to constrain the type of arguments in a variadic constructor?"

是的。一种方法(最好的方法?我不确定)是在额外的模板参数上使用 SFINAE,如下所示:

struct X {
    template<
        class... TT,
        class E = std::enable_if_t<(std::is_same_v<TT, int> && ...)>
    >
    X(TT... tt) {
        // do stuff with the ints "tt..."
    }
};

&& ... 是折叠表达式,C++17 中的新功能。如果您的编译器不支持折叠表达式,只需将其替换为手动 all_of.