通过模板函数调用未知类型的方法
Calling a method on an unknown type through a template function
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 的源代码,因此无法对它们进行更改。 (例如,我不能让它们继承自一个共同的基础 class 并使用动态多态性而不是模板函数来达到相同的效果)。
这个完全OK,很多情况下都会用到。例如,处理标准库中的通用容器或不同类型的迭代器。
如果传入的类型没有合适的方法,您将得到一个编译错误。
如果您愿意,可以使用 SFINAE 来确保传入的类型是您期望的类型。有时可能很好或有用,但通常不需要。
更新: static_assert
是@Evgeny
指出的另一种对模板施加约束的有用方法
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 的源代码,因此无法对它们进行更改。 (例如,我不能让它们继承自一个共同的基础 class 并使用动态多态性而不是模板函数来达到相同的效果)。
这个完全OK,很多情况下都会用到。例如,处理标准库中的通用容器或不同类型的迭代器。
如果传入的类型没有合适的方法,您将得到一个编译错误。
如果您愿意,可以使用 SFINAE 来确保传入的类型是您期望的类型。有时可能很好或有用,但通常不需要。
更新: static_assert
是@Evgeny