在Visual C ++ 2017(使用/std:c++14
或/std:c++17
)中,以下代码有效:
void TakePtr(char*); // const or not
int main()
{
TakePtr(char{});
TakePtr(char());
}
我不明白为什么会这样。
显然,以下操作也可以(按预期方式):
void TakeChar(char);
TakeChar(char{});
TakeChar(char());
在将char
或char*
用作参数时,编译器如何将类型char{}
推论(或转换为char()
?
现在,如果我同时具有char
和char*
重载,那么它将正常工作而不会出现任何错误/警告歧义:
void TakePtr(char*);
void TakePtr(char);
TakePtr(char{}); // Chooses 'char'
TakePtr(char()); // Chooses 'char'
为什么char{}
的{{1}}可以使用编译器?
为什么选择更好版本时,为什么不给出警告/错误?这种行为势必会破坏现有代码。
可以肯定,编译器不满意:
TakePtr(char*)
答案 0 :(得分:13)
因为视觉说谎很多。尤其是年龄较大的一个。您的代码提示clang报告错误:
<source>:9:6: error: no matching function for call to 'TakePtr'
TakePtr(char{});
^~~~~~~
<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument
void TakePtr(char*); // const or not
^
<source>:10:6: error: no matching function for call to 'TakePtr'
TakePtr(char());
^~~~~~~
<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument
void TakePtr(char*); // const or not
^
2 errors generated.
就遵循C ++标准而言,Visual被认为是“奇异的”,因此不要过于依赖它。请确保使用clang / gcc进行验证。
答案 1 :(得分:3)
这仅仅是MSVC的背后:C ++ 03中的规则是整数类型和值0的 any 常量表达式是一个空指针常量,因此可以转换为{{1} }。当然char*
是合格的,而char()
的意思是相同的,尽管它从未与规则重叠。