如果我有一个复杂的函数,我想用于两个具有匹配接口的集合(至少就所讨论的函数而言)是否有办法重新使用模板代码?
例如:
void DoSomethingIntense(std::vector<blah> myBlah);
void DoSomethingIntense(std::array<blah> myBlah);
如果我使用数组和向量共有的开始,结束,大小和其他函数,有没有办法重复使用DoSomethingIntense的主体而不键入两次(或者,天堂禁止,将其填入宏)?
(请不要挑选示例代码,它不会帮助任何人)
更新:道歉,我忽略了提到有问题的函数对于与此签名不匹配的类有其他实现;只是让每个参数都使用适用于这两个的代码不是一种选择。
我认为迭代器解决方案在这种情况下可能是最好的。
答案 0 :(得分:3)
是的,使用模板。
template <typename Container>
void DoSomethingIntense(Container blah) { // Might be better as Container const &
// write code using blah.begin() or whatever
}
通过支持一般的迭代器范围而不是特定的容器,你可能能够使它更加通用,遵循STL的例子:
template <typename Iterator>
void DoSomethingIntense(Iterator begin, Iterator end);
答案 1 :(得分:1)
是的,您可以使用模板实现这一目标:
template<typename T>
void DoSomethingIntense(const T &myBlah);
编辑:
如果我的更新正确,那么我会说使用SFINEA:
template<typename T>
struct is_vector : std::false_type {};
template<typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type {};
template<typename T>
struct is_array : std::false_type {};
template<typename T, size_t N>
struct is_array<std::array<T, N>> : std::true_type {};
// add more if you want or define a macro
template<typename T>
std::enable_if_t<is_vector<T>::value || is_array<T>::value, void>
DoSomethingIntense(const T &myBlah)
{
}
int main()
{
std::vector<int> v;
DoSomethingIntense(v); // OK
std::array<float, 5> a;
DoSomethingIntense(a); // OK
std::queue<int> q;
DoSomethingIntense(q); // ERROR
}
答案 2 :(得分:0)
您可以混合模板/重载。没问题。
例如:
template <typename T>
void DoSomethingIntense(T myBlah) {
}
void DoSomethingIntense(MyCustomClass myBlah) {
}
然后它将使用参数类型MyCustomClass
的非模板版本和其他任何内容的模板版本(例如vector
或array
)
此外,您可以使用std::enable_if来限制可能的模板参数范围。另请参阅this question。