如何定义方法签名以便它接受与可变参数模板类定义相同数量的参数?例如如何定义数组类:
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
.
我找到了 decltype
比 using
更难理解触摸, 特别是如果你想将参数的类型更改为不同于 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
,比方说)。
另一种方法是让您的 operator()
取一组值,比如 std::array<sizeof...(Shape), int>
.来电者必须:
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 运算符重载。
我会推荐标签调度,但我看不出有什么方法可以使它比 SFINAE 解决方案更干净,额外的 decltype
和所有错误消息,或者比 static_assert
更好的错误消息另一方面版本。
关于c++ - 可变参数模板与类中的函数参数数量相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26766617/