问题描述
如何定义方法签名,以便接受与可变模板类定义相同数量的参数?例如,如何定义一个Array类:
How to define method signature so it will accept same number of arguments as variadic template class definition? For example how to define an Array class:
template<typename T, int... shape>
class Array
{
public:
T& operator () (???);
};
所以你可以这样调用:
Array<int, 3, 4, 5> a;
a(1, 2, 3) = 2;
推荐答案
template<class T, int...Shape>
class Array {
template<int>using index_t=int; // can change this
public:
T& operator()(index_t<Shape>... is);
};
或:
template<class T, int...Shape>
class Array {
public:
T& operator()(decltype(Shape)... is);
};
或:
template<class T, int...Shape>
class Array {
public:
T& operator()(decltype(Shape, int())... is);
};
如果您想要将参数的类型更改为 Shape
。
if you want to be able to change the type of the parameter to be different than Shape
.
我发现 decltype
使用
,特别是如果您要将参数的类型更改为不同于 int
。
I find the decltype
harder to understand a touch than the using
, especially if you want to change the type of the parameter to be different than int
.
另一种方法:
template<class T, int...Shape>
class Array {
public:
template<class...Args,class=typename std::enable_if<sizeof...(Args)==sizeof...(Shape)>::type>
T& operator()(Args&&... is);
};
使用SFINAE。但它并不强制 Args
是整数类型。如果我们想要添加另一个子句(所有的 Args
可以转换为 int
,说)。
which uses SFINAE. It does not enforce that the Args
are integer types however. We could add another clause if we wanted to (that all of the Args
are convertible to int
, say).
另一种方法是让运算符()
获取一组值,例如 std :: array< sizeof ...(Shape),int>
。调用者必须:
Yet another approach is to have your operator()
take a package of values, like a std::array<sizeof...(Shape), int>
. Callers would have to:
Array<double, 3,2,1> arr;
arr({0,0,0});
使用一组 {}
最后一种方法是:
template<class T, int...Shape>
class Array {
public:
template<class...Args>
auto operator()(Args&&... is) {
static_assert( sizeof...(Args)==sizeof...(Shapes), "wrong number of array indexes" );
}
};
我们接受任何内容,如果参数数量错误,则会生成错误。这会产生非常干净的错误,但不会执行正确的SFINAE运算符重载。
where we accept anything, then generate errors if it is the wrong number of arguments. This generates very clean errors, but does not do proper SFINAE operator overloading.
我会建议标记分派,但我没有看到一个方法,另一方面,SFIAE解决方案具有额外的 decltype
和所有或更好的错误消息比 static_assert
版本。
I would recommend tag dispatching, but I don't see a way to make it much cleaner than the SFINAE solution, with the extra decltype
and all, or better error messages than the static_assert
version on the other hand.
这篇关于变量模板与类中的函数参数数量相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!