我很困惑为什么编译器(g ++ ver 4.8.4)在编译以下代码片段时遇到问题。在调用x.addField("hi", s.size());
中,我认为编译器可以简单地使用方法void addField(const char *fieldName, long value)
,因为它显然是最佳匹配。
#include <string>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
class strDum {
public:
void addField(const char *fieldName, const char *fmt, ...);
void addField(const char *fieldName, bool value);
void addField(const char *fieldName, long value);
void addField(const char *fieldName, double value);
};
void strDum::addField(const char *fieldName, const char *fmt, ...) {
}
void strDum::addField(const char *fieldName, bool value) {
}
void strDum::addField(const char *fieldName, long value) {
}
void strDum::addField(const char *fieldName, double value) {
}
int main(int argc, char *argv[] )
{
string s = "hello";
strDum x;
x.addField("hi", s.size());
return 0;
}
这是编译器错误消息
$ g++ -std=c++11 te4.cc
te4.cc: In function ‘int main(int, char**)’:
te4.cc:29:27: error: call of overloaded ‘addField(const char [3], std::basic_string<char>::size_type)’ is ambiguous
x.addField("hi", s.size());
^
te4.cc:29:27: note: candidates are:
te4.cc:16:6: note: void strDum::addField(const char*, const char*, ...) <near match>
void strDum::addField(const char *fieldName, const char *fmt, ...) {
^
te4.cc:16:6: note: no known conversion for argument 2 from ‘std::basic_string<char>::size_type {aka long unsigned int}’ to ‘const char*’
te4.cc:18:6: note: void strDum::addField(const char*, bool)
void strDum::addField(const char *fieldName, bool value) {
^
te4.cc:20:6: note: void strDum::addField(const char*, long int)
void strDum::addField(const char *fieldName, long value) {
^
te4.cc:22:6: note: void strDum::addField(const char*, double)
void strDum::addField(const char *fieldName, double value) {
^
有什么想法吗?
答案 0 :(得分:3)
此调用中的参数:
x.addField("hi", s.size());
有{const char[3], size_t}
类型。对于这组参数,我们有三个可行的重载候选者:
void addField(const char*, bool );
void addField(const char*, long );
void addField(const char*, double );
在每种情况下,size_t
都可以通过积分转换(size_t
到bool
或size_t
到long
)转换为第二种参数类型,或者浮动积分转换(size_t
到double
)。这些转换都没有比其他转换更好 - 它们都具有相同的排名:转换。因此,没有最佳可行的候选人,因为我们无法区分这三个选项。
混淆的一个原因可能是long
比size_t
“更接近”bool
。但从转换排名的角度来看,这无关紧要。它们都涉及积分转换,并且在不同的积分转换类型之间没有区别 1 。
消除歧义:
addField(const char*, size_t)
x.addField("hi", static_cast<long>(s.size()))
template <class T> void addField(const char*, T)
可能你会想要最后一个。
1 是促销(例如char
到int
)和积分之间的区别转换虽然(例如int
到char
)。促销是比转化更好的转化。