C ++函数专业化不允许?

时间:2012-01-04 04:41:17

标签: c++ templates specialization

这是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)

有人能帮助我吗?

2 个答案:

答案 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

也就是说,这里有一些与模糊性和专业化无关的程序随机注释:

  • 在C ++ 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>).