C++模板编程


636 浏览 5 years, 4 months

3.2 函数模板重载

版权声明: 转载请注明出处 http://www.codingsoho.com/

函数模板重载

还可以用非模板函数重载模板函数。例如如果不编写char*的Find()模板特例化,还可以编写一个非模板的Find()函数直接操作char*:

size_t Find(char*& value, char** arr, size_t size)
{
    cout << "overload" << endl;
    for (size_t i = 0; i < size; i++) {
        if (strcmp(arr[i], value) == 0) {
            return i; // found it; return the index
        }
    }
    return NOT_FOUND; // Failed to find it; return NOT_FOUND
}

这个函数的行为等同于前一节中特例化的版本的行为。然而,这个函数的调用规则有所不同:

char* word = "two";
char* arr[] = {"one", "two", "three", "four"};
size_t sizeArr = sizeof(arr) / sizeof(arr[0]);
size_t res;
res = Find<char*>(word, arr, sizeArr); // Calls the Find template with T=char*
res = Find(word, arr, sizeArr);        // Calls the Find non-template function.

因此,如果想要让函数能够在显式指定了char*的时候能正常工作,以及在没有指定的时候能通过自动类型推导正常工作,那么应该编写一个特例化的模板版本,而不是写一个非模板的重载版本。

与模板类方法定义一样,函数模板定义(不只是原型)必须对使用这些函数模板的所有源代码文件可用。因此,如果多个源代码文件使用了定义,应该将定义放在头文件中。

1、同时使用函数模板重载和特例化

可同时编写一个适用于char*的特例化Find()模板,以及一个独立的接受char*的Find()函数。编译器总是优先选择非模板化的函数函数而不是模板化的版本。然而,如果显式地指定模板的实例化那么会强制编译器使用模板化的版本:

char* word = "two";
char* arr[] = {"one", "two", "three", "four"};
size_t sizeArr = sizeof(arr) / sizeof(arr[0]);
size_t res;
res = Find<char*>(word, arr, sizeArr); // Calls the char* specialization of the template
res = Find(word, arr, sizeArr);        // Calls the Find non-template function.