[英]How can I create a C++ constructor that accepts a variable number of int's
Is it possible to constrain the type of arguments in a variadic constructor? 是否可以约束可变参数构造函数中的参数类型?
I want to be able to express 我希望能够表达
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...)
{
}
};
edit to clarify intent: 编辑以澄清意图:
What I want to achieve is to store data passed into a constructor (constants known at compile time) into a static array. 我想要实现的是将传递给构造函数的数据(编译时已知的常量)存储到静态数组中。
so there are some other 所以还有其他一些
template<int ...values>
struct Z
{
static int data[sizeof...(values)];
};
template<int ... values>
int Z<values...>::data[sizeof...(values)] = {values...};
and in the constructor of XI would like to use Z like this: 并且在XI的构造函数中想要像这样使用Z:
class X {
template<int ... Args> X(Args...)
{
Z<Args...>::data // do stuff with data
}
};
Is that possible, our do I have to use integer_sequence? 这可能,我们必须使用integer_sequence吗?
You can use std::initializer_list
: 你可以使用
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!
}
Since you have the following: 由于您有以下内容:
template<int... values>
struct Z
{
static int data[ sizeof...( values ) ];
};
template <int... values>
int Z<values...>::data[ sizeof...( values ) ] = { values... };
You can use std::integer_sequence<>
to pass in the ints to Z<>
: 您可以使用
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
}
};
You can make yourself a helper type to make it easy to call the ctor: 你可以让自己成为帮手类型,以便轻松调用ctor:
template <int... values>
using int_sequence = std::integer_sequence<int, values...>;
Then you can instantiate your class like so: 然后你可以这样实例化你的类:
int main()
{
X x( int_sequence<1, 3, 5>{} );
}
You've updated your question to indicate that all you need is a compile-time std::integer_sequence
, which is great. 你已经更新了你的问题,表明你需要的只是一个编译时
std::integer_sequence
,这很棒。
But just for the sake of future readers who might come here looking for the answer, I'd like to also answer your original question "Is it possible to constrain the type of arguments in a variadic constructor?" 但只是为了未来可能会来这里寻找答案的读者,我还想回答你原来的问题“是否有可能限制变量构造函数中的参数类型?”
Yes. 是。 One way (the best way? I'm not sure) is to SFINAE on an extra template parameter, like this:
一种方法(最好的方法?我不确定)是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..."
}
};
The && ...
is a fold-expression, new in C++17. && ...
是一个fold-expression,在C ++ 17中是新的。 If your compiler doesn't support fold-expressions, just replace that with a hand-rolled all_of
. 如果您的编译器不支持fold-expression,只需用手动的
all_of
替换它。
No, you can't constrain the type. 不,你不能限制类型。 You can use
static_assert
though. 你可以使用
static_assert
。 Would be something like this: 会是这样的:
static_assert(std::is_same<int, Args>::value ..., "have to be ints.");
Have not tried to use an expansion in a static_assert
like that though. 尽管如此,还没有尝试在
static_assert
使用扩展。 You may need a constexpr that returns bool or something. 你可能需要一个返回bool或其他东西的constexpr。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.