您的原始代码无法编译
您向我们展示的代码
#include <iostream>
#include <string>
class ADDON {
std::string s;
public:
ADDON() {
s = "";
}
ADDON(std::string in) {
s = in;
}
ADDON(const char in[]) {
s = in;
}
void operator=(const std::string in) {
s = in;
}
std::string getString() {
return s;
}
};
template<typename T>
void print_to_default_file(T &obj, ADDON addon = "")
{ std::cout << "first overload\n"; }
template<typename T>
void print_to_default_file(T &obj, std::string objS)
{ std::cout << "second overload\n"; }
int main()
{
print_to_default_file("test","where will I go");
}
不编译(在线输出),出现以下错误
prog.cpp:在函数'int main()'中:prog.cpp:39:52:错误:重载'print_to_default_file(const char [5],const char [16])'的调用不明确 prog.cpp:39: 52:注意:候选人是:prog.cpp:30:6:注意:void print_to_default_file(T&, ADDON) [with T = const char [5]] prog.cpp:34:6: 注意:void print_to_default_file(T&, std ::string) [with T = const char [5]; std::string = std::basic_string]
原因是名称查找和参数推导找到 2 个候选者:第一个重载需要一个const char*
toADDON
转换,第二个重载需要一个const char*
tostd::string
转换。两种转换序列都是同样好的匹配,并且重载解决方案不明确,并且您的程序格式错误。
一个简单的修复
只需将第二个重载更改为采用const char*
as 参数(而不是 as char*
,它不能绑定字符串文字),它将是原始字符串文字作为参数的最佳匹配
template<typename T>
void print_to_default_file(T &obj, const char* objS) // but NOT char* objS
{ std::cout << "second overload\n"; }
您现在将获得第二个重载(在线输出)。要选择第一个重载,只需调用ADDON
参数列表中的构造函数
int main()
{
print_to_default_file("test", ADDON("where will I go"));
}
请注意,这将调用ADDON(const char[])
构造函数而不是构造函数ADDON(std::string)
,因为后者需要用户定义的转换(在线输出)。
正确的修复
使用非显式的单参数构造函数是极其危险的。始终explicit
在此类函数周围使用关键字。
class ADDON {
std::string s;
public:
ADDON() {
s = "";
}
explicit ADDON(std::string in) {
s = in;
}
explicit ADDON(const char in[]) {
s = in;
}
void operator=(const std::string in) {
s = in;
}
std::string getString() {
return s;
}
};
这也将调用第二个重载(在线输出),因为ADDON
重载没有显式调用任何构造函数。要选择第一个重载,请再次调用ADDON
参数列表中的构造函数。