这是C ++中函数特化的一个非常简单的例子。我认为它应该可以工作,但Visual Studio的编译器给我一个含糊不清的信息。
template <class T> T min(T a, T b) {
if(a < b) return a;
else return b;
}
string min(string str1, string str2) {
if(str1.length() < str2.length()) return str1;
return str2;
}
void main(int argc, char* argv[])
{
int n=12, p=15;
string str1= "monsieur", str2= "bonjour" ;
cout << min(n,p) << endl;
cout << min(str1, str2) << endl;
}
实际上它说“min(n,p)是不明确的,不知道要调用哪个函数。这可能是一个微不足道的问题,但我还没有弄清楚问题。我也尝试了以下标题:
template<> string min(string str1, string str2)
和
template<> string min<string>(string str1, string str2)
有人能帮助我吗?
答案 0 :(得分:2)
您的问题可能是由于min
在其他地方(可能是标准库)的定义冲突造成的。尝试将您的功能重命名为my_min
或其他内容。
更改函数名称使我的示例正确编译。
答案 1 :(得分:2)
不需要转换的非模板始终是更好的匹配。也就是说,如果这些是min()
的唯一定义,那么就没有问题(即将函数min
重命名为其他东西会消除歧义)。模糊性介于template <typename T> T const& std::min(T const&, T const&)
和你模板化的版本之间。另一个修复是删除using声明并显式限定名称空间std
中的名称,即以下代码编译正常:
#include <iostream>
#include <string>
template <class T> T min(T a, T b) {
return a < b? a: b;
}
std::string min(std::string str1, std::string str2) {
return str1.length() < str2.length()? str1: str2;
}
int main()
{
int n=12, p=15;
std::string str1= "monsieur", str2= "bonjour" ;
std::cout << min(n,p) << "\n";
std::cout << min(str1, str2) << "\n";
}
请注意,您std::string
的{{1}}版本不专业化,但过载!在调用函数时,这并不重要,它将按预期选择版本。但是,在显式指定模板参数时调用该函数时,它不会:
min()
(*)实际上,由于参数依赖查找,min(str1, str2); // calls string overload
min<std::string>(str1, str2); // calls the function template (*)
与名称空间min<std::string>(str1, str2)
的版本再次不明确;如果它的名称不同,则会调用模板版本。
如果你想真正专注于这个功能,你会写这样的东西:
std
也就是说,这里有一些与模糊性和专业化无关的程序随机注释:
template <> std::string min<std::string>(std::string, std::string) { ... }
中必须声明始终以返回main()
。允许在int
中省略return语句,但有些编译器没有这样做。对于可移植代码,您最好使用main()
返回并返回int
(或0
EXIT_SUCCESS declared in <stdlib.h>
).
declared in <stdlib.h>
).