sim*_*ser 2 c++ templates overloading overload-resolution implicit-conversion
我有一个功能模板(c ++)
template<typename T>
void print_to_default_file(T &obj, ADDON addon = "")
Run Code Online (Sandbox Code Playgroud)
和一个重载的功能
template<typename T>
void print_to_default_file(T &obj, std::string objS) // or char* objS
Run Code Online (Sandbox Code Playgroud)
该类ADDON具有以下签名的运算符重载
void operator=(const std::string)
Run Code Online (Sandbox Code Playgroud)
问题是,当我执行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;
}
};
Run Code Online (Sandbox Code Playgroud)
您向我们展示的代码
#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");
}
Run Code Online (Sandbox Code Playgroud)
不编译(在线输出),出现以下错误
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*,以ADDON转换,第二个过载const char*来std::string转换.两个转换序列都是同样好的匹配,并且过载资源不明确且您的程序格式错误.
只需更改第二个重载以获取const char*as参数(而不是char*,不能绑定字符串文字),它将是原始字符串文字作为参数的最佳匹配
template<typename T>
void print_to_default_file(T &obj, const char* objS) // but NOT char* objS
{ std::cout << "second overload\n"; }
Run Code Online (Sandbox Code Playgroud)
您现在将获得第二次重载(在线输出).要选择第一个重载,只需ADDON在参数列表中调用构造函数即可
int main()
{
print_to_default_file("test", ADDON("where will I go"));
}
Run Code Online (Sandbox Code Playgroud)
请注意,这将调用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;
}
};
Run Code Online (Sandbox Code Playgroud)
这也将调用第二个重载(在线输出),因为ADDON重载不会显式调用任何构造函数.要选择第一个重载,请再次ADDON在参数列表中调用构造函数.
| 归档时间: |
|
| 查看次数: |
137 次 |
| 最近记录: |