C ++语言允许我编写一个模板函数,该函数将在传递给该函数的对象上调用一个方法。
这里的问题是,当我这样做时,我的IDE(NetBeans 8.2)会抱怨它无法解析该方法。这是有道理的,因为直到我尝试编译代码之前,都不知道将用于“ T”的类型,但是它给我警告的事实使我有点担心这样做是否是不好的编程习惯。
考虑以下代码:
struct S1 {
void method() const {
cout << "Method called from S1!" << endl;
}
};
struct S2 {
void method() const {
cout << "Method called from S2!" << endl;
}
};
template <typename T>
void call_method(const T& object) {
// IDE reports a warning "can't resolve the template based identifier method."
object.method();
}
用法示例:
S1 obj1;
S2 obj2;
call_method(obj1);
call_method(obj2);
该代码可以编译并正常工作,但是IDE总是会抱怨。这样可以吗?还是有我应该知道的更好的设计来获得相同的预期结果。
期望的结果是编写一个可以使用S1或S2对象而不关心它是哪一个的函数,只要它们提供包含“ method()”的接口即可。
假定我无法访问S1和S2的源代码,因此无法对其进行更改。 (例如,我不能使它们从通用基类继承并使用动态多态性而不是模板函数来达到相同的效果。)
答案 0 :(得分:5)
这完全可以,并且在很多情况下通常使用。例如,处理标准库中的通用容器或不同类型的迭代器。
如果传入的类型没有适当的方法,则会出现编译错误。
如果需要,可以使用SFINAE来确保传入的类型属于您期望的类型。有时可能是好的或有用的,但通常并不需要。
更新:static_assert
是@Evgeny指出的在模板上施加约束的另一种有用方法