我有自定义数据结构。
template<class T> class MyArray3D{
public: void setElement(const int* index,const T& t){
//do something about "index[0,1,2]"
}
public: T& get(const int* index){
//do something about "index[0,1,2]"
}
public: void reserve(const int* index1,const int* index2){
//do something about "index1,2[0,1,2]" (e.g. index can be negative)
}
//about 20 functions, and some fields
};
一切都很好。它目前被许多类使用
然后我希望这些函数接受具有index
。
operator[]
)
这是一种正确(但不是很好)的方法
我将const int*
更改为template INT_ARRAY
: -
template<class T> class MyArray3D{
public: template<class IARRAY> void setElement(IARRAY index,const T& t){
//do something about "index[0,1,2]"
}
public: template<class IARRAY> T& get(IARRAY index){
//do something about "index[0,1,2]"
}
public: template<class IARRAY1,class IARRAY2>
void reserve(IARRAY1 index1,IARRAY2 index2){
//do something about "index1,2[0,1,2]" (e.g. index can be negative)
}
//about 20 functions, and some fields
};
上述重构是乏味的。我必须为所有功能做到这一点。
如果一个函数有4 const int*
,它将以template<class IARRAY1,class IARRAY2,class IARRAY3,class IARRAY4>
为前缀 - 太丑了。
如何优雅地重构上述功能(重复性较低,代码较短)?
我在做着类似的事情: -
template<class T> class MyArray3D{
using IARRAY1 = please don't care about my type; ????
public: void setElement(IARRAY1 index,const T& t);
public: T& get(IARRAY1 index);
public: void reserve(IARRAY1 index1,IARRAY1 index2);
};
以下是相关问题:
答案 0 :(得分:3)
不幸的是,如果你想要模板函数参数演绎并接受任何类型,这是正确的方法,尽管它不简洁。
希望将来我们会得到abbreviated Concepts Lite syntax,这样你就可以做到:
concept bool Indexable = /* ... */;
template<class T> class MyArray3D{
public:
void setElement(Indexable index, const T& t);
T& get(Indexable index);
void reserve(Indexable index1, Indexable index2);
};
答案 1 :(得分:1)
一些想法:
template <typename... T>
void foo(T&&... args)
{
auto tuple = std::make_tuple(std::forward<T>(args)...);
auto indexer1 = std::get<0>(tuple);
auto indexer2 = std::get<1>(tuple);
auto indexer3 = std::get<2>(tuple);
auto indexer4 = std::get<3>(tuple);
// etc
}
如果您的索引器访问连续内存,您可以使用GSL's span而不是索引器返回的类型T
(或借用这个想法并编写自己的内容):
template <typename T>
void foo(span<T> indexer1, span<T> indexer2, span<T> indexer3, span<T> indexer4)
{
}