在有关 C++ 的书籍中,当我们在 C++ 中有可供使用的模板时,为什么要教我们使用函数重载?
展示模板的有效(和正确)使用不是更好吗?与大多数 C++ 书籍中教授函数重载的地方相反?
或者,是否有充分的理由使用其中一个而不是另一个?
在有关 C++ 的书籍中,当我们在 C++ 中有可供使用的模板时,为什么要教我们使用函数重载?
展示模板的有效(和正确)使用不是更好吗?与大多数 C++ 书籍中教授函数重载的地方相反?
或者,是否有充分的理由使用其中一个而不是另一个?
当您想要对可能不同的类型执行相同的操作时,模板提供了一个优势。一个简单的例子:
template <typename T>
T foo(const T& a, const T& b) { return a + b; }
当您想根据类型应用不同的操作时,可以使用重载:
struct Foo{ void foo() const {} };
void foo(int i) { std::cout << "i = " << i << "\n"; }
void foo(const Foo& f) { f.foo(); }
您可以使用模板和模板特化来实现上述目的,但是这种特化应该代表一般情况的一些例外情况。
模板不能接受不同数量的参数。重载可以。此外,模板表明您可以对任何数据类型进行操作,但实际上,绝大多数模板只是专门化的(在您的系统中),表示这一点是没有意义的。此外,重载可以virtual
,模板特化不能。专业化的特征也不能与基础不同。
template<typename T> void foo(T& t);
template<> void foo<std::string>(std::string* ptr); // Illegal
void foo(std::string* ptr); // Legal
与当前系统相比,这将严重限制您可能产生的过载类型。
当您想要对许多不同的数据类型执行相同的操作时,通常会使用模板。
当您想对某些数据集执行不同的操作时,通常会使用函数重载。
在您想要对许多不同的数据类型执行相同的操作集的情况下,模板的优势在于编译器将在编译时为您处理您将来可能创建的使用模板化函数的任何可能的新类型。如果要使用函数重载,则每次创建要传递给特定函数的新类型时都必须创建新的函数重载。
只是对 juanchopanza 的回答的补充:
使用函数重载,您还可以改变参数的数量,这很方便。
一个简单的例子,如果你有一些具有以下声明的函数:
void foo(int i, int j);
但是您经常使用第一个参数 0 调用 foo,您可以编写以下函数来节省一些输入。
void foo(int j) {
foo(0, j);
}
模板(通常)要求您使用相同的语法来对所有(支持的)类型执行操作。
函数重载(或应该)类似地使用,但允许您使用不同的语法来执行不同类型的操作。也就是说(尽管您不必这样做)您可以用不同的方式表示这些值。一个明显的例子是在 C 库中被调用atan
的内容。atan2
使用atan
,我们传递“上升到“运行”的比率,并返回该比率所代表的角度。atan2
我们传递上升的值并分别运行(计算大致相同的结果,但因为它稍微给出更多的输入数据,也可以产生更完整的结果)。
尽管这些在 C 中实现为完全独立的函数,但如果它们从一开始就用 C++ 编写,则完全适合对atan
一个参数和两个参数使用重载的单个名称(例如,):
double atan(double); // equivalent to current atan
double atan(double, double); // equivalent to current atan2
模板(缺乏专业化,几乎只是覆盖模板本身提供的内容)不提供这样的调用语法差异。
重载也受到更多限制——您为要支持的每种特定类型提供一个重载(尽管如果您采用指针或引用,它们也可以支持派生类型)。使用模板,单个模板可以(至少可能)适用于任何类型。
所以两者overloading
各有千秋template
。
关于它们的一行difference
是:
overloading
当我们有各种功能,做SIMILAR
操作时使用。
template
当我们有各种功能,做IDENTICAL
操作时使用。
There is very big differnce between "SIMILAR" and "IDENTICAL".