我有一个函数模板 (c++)
template<typename T>
void print_to_default_file(T &obj, ADDON addon = "")
和一个重载函数
template<typename T>
void print_to_default_file(T &obj, std::string objS) // or char* objS
类ADDON
具有以下签名的运算符重载
void operator=(const std::string)
问题是当我这样做时 print_to_default_file("测试","我要去哪里")
它正在调用第一个,但我想调用第二个。我也厌倦了 char * 而不是 std::string 但结果是相同的。
谁能指出哪里错了
ADDON简化版
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;
}
};
最佳答案
您的原始代码无法编译
您向我们展示的代码
#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");
}
无法编译( online output )并出现以下错误
prog.cpp: In function ‘int main()’: prog.cpp:39:52: error: call of overloaded ‘print_to_default_file(const char [5], const char [16])’ is ambiguous prog.cpp:39:52: note: candidates are: prog.cpp:30:6: note: void print_to_default_file(T&, ADDON) [with T = const char [5]] prog.cpp:34:6: note: void print_to_default_file(T&, std::string) [with T = const char [5]; std::string = std::basic_string]
原因是名称查找和参数推导找到了 2 个候选:第一个重载需要 const char*
到 ADDON
转换,第二个重载需要 const char*
到 std::string
转换。两个转换序列都同样良好匹配,并且重载结果不明确,并且您的程序格式错误。
一个简单的修复
只需更改第二个重载以采用 const char*
作为参数(而不是作为 char*
,它无法与字符串文字绑定(bind)),这将是最好的匹配原始字符串文字作为参数
template<typename T>
void print_to_default_file(T &obj, const char* objS) // but NOT char* objS
{ std::cout << "second overload\n"; }
您现在将获得第二个过载 ( online output )。要选择第一个重载,只需调用参数列表中的ADDON
构造函数
int main()
{
print_to_default_file("test", ADDON("where will I go"));
}
请注意,这将调用 ADDON(const char[])
构造函数,而不是 ADDON(std::string)
构造函数,因为后者需要用户-定义的转换( online output )。
正确的修复
使用非显式的单参数构造函数是极其危险的。始终在此类函数周围使用 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;
}
};
这还将调用第二个重载 ( online output ),因为 ADDON
重载不会显式调用任何构造函数。要选择第一个重载,请再次调用参数列表中的 ADDON
构造函数。
关于C++ 运算符重载参数与普通参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16418821/