我试图清除一些使用char*
和std::string
的代码,并遇到了以下代码所示的问题。
void Foo( int xIn , const std::string & fooIn )
{
std::cout << "string argument version called \n";
}
void Foo( int xIn , bool flagIn = true )
{
std::cout << "bool argument version called \n";
}
int main()
{
int x = 1;
Foo( x , "testing" );
return 0;
}
当我运行程序时,我得到名为的 bool参数版本。 char*
到bool
的转化优先于char*
到const std::string&
,还是Visual Studio 2008对我有耍技巧?
答案 0 :(得分:27)
令人惊讶的是,这种行为是合规的,编译器是合规的:char*
到bool
转换比转换为std::string
更受欢迎。
了解更多here。
C ++标准中详细说明了确切的规则。它们非常复杂,但以下段落至关重要:
C ++ 11 13.3.3.2对隐式转换序列进行排名[over.ics.rank]
2 比较隐式转换序列的基本形式(如 在13.3.3.1)中定义 - 标准转换序列(13.3.3.1.1)是 比用户定义的转换序列更好的转换序列 或省略号转换序列
char*
- 至 - bool
需要“标准转换序列”,而char*
- 至 - string
需要“用户定义的转换序列”。因此,前者是首选。
答案 1 :(得分:9)
它们都是潜在匹配,但编译器首选bool
版本,因为为了匹配用户提供的string
版本(或者,在这种情况下,提供库)转换功能是必需的。
如果您真的想要这样做,为const char*
提供重载可以帮助您:
void Foo( int xIn, const char* in)
{
return Foo( xIn, string(in) );
}
我猜想通过这样做,编译器很可能会对它进行相当多的优化。
答案 2 :(得分:1)
一个简单的解决方法是将bool
更改为int
- 从指针bool
隐式转换,但不转换为int
。 bool
到int
不是问题,因此传递bools的现有代码将继续有效。
不幸的是,通过屏蔽参数的意图,这确实会影响代码的可读性。