我有一个作用于元素列表的类,就像这样:
template <typename T>
class MyClass {
...
};
我需要实现在vector<T>
和string
上都可以使用的某些方法-这是大多数用户将对象初始化为MyClass<char>()
时使用的方法。
由于这个原因,我被迫遵循这种超载模式:
void method(vector<T> elements){
}
void method(string elements){
method(convertStringToVector(elements));
}
其中vector<char> convertStringToVector(string str)
的定义符合预期。
也就是说,对于每个类方法,我都不得不添加一个对string
重载的附加方法。我发现这是不必要的开销,有时也忘记添加它。
我将在字符串上做与在相应向量上做的完全相同的事情-在两种情况下,相同的迭代等情况下都将调用相同的方法。因此,我想知道是否有更清洁的方法这样,无需增加太多代码开销。有吗?
答案 0 :(得分:5)
一种可能的方法是将您的方法实现为模板,其参数不限于string
或vector<char>
。
template <typename T>
struct MyClass
{
template <class C>
void method(C container);
};
这可以解决您的问题,因为在两种情况下一个实现就足够了:
template <typename T>
template <class C>
void MyClass<T>::method(C container)
{
std::cout << "Container has size " << container.size() << '\n';
std::cout << "First element is " << container[0] << '\n';
}
但是,这将适用于任何容器。尚不清楚这是好(代码是通用的)还是坏的(代码允许不良的实例化)。
想象一下,当人们尝试错误地向您的方法发送vector<int>
而不是vector<char>
时会发生什么。因为您没有为这种情况构建代码,所以它要么显示模糊的编译错误,要么生成在运行时以静默方式执行错误操作的代码。
答案 1 :(得分:2)
您可以创建一个类用作方法的参数,该类同时接受std::vector<char>
和std::string
:
class MyString
{
public:
MyString(const std::vector<char>& v) : vector(v) {}
MyString(std::vector<char>&& v) : vector(std::move(v)) {}
MyString(const std::string& s) : vector(convertStringToVector(s)) {}
std::vector<char> vector;
};
void method(MyString elements)
{
}
答案 2 :(得分:0)
您可以像这样将_index
定义为类的方法:
convertStringToVector
或单独的模板函数,如果您需要其他类单独使用它。
我也将参数作为引用vector<T> convertStringToVector(string str)
传递。
如果您使用的任何模板参数与算法不兼容,编译器都会告诉您。
对于那些特殊情况,您仍然可以像这样编写模板专业化:
const string &str
并为此template<>
vector<SPECIALTYPE> convertStringToVector<SPECIALTYPE>(string str)
{
...
}
实现不同的代码。