【发布时间】:2019-11-04 06:05:10
【问题描述】:
在 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{} 为 TakePtr(char*)?
为什么选择 better 版本时它不给出警告/错误?这种行为势必会破坏现有代码。
当然,编译器不满意:
void TakePtr(char*);
char c{};
TakePtr(c);
【问题讨论】:
-
一个疯狂的猜测:
char()构造一个临时的(char)0,它可以转换为任何整数0,它被接受为空指针。我在 Godbolt 中测试过,我相信我是对的:Compiler Explorer. -
@Scheff,
xor ecx, ecx; call void TakePtr(char *). -
@Evg Yepp。这就是为什么我相信我是对的。 ;-)
-
可能可以通过添加
void TakePtr(char) = delete;来压制不良行为 -
@Scheff,加油!
TakePtr(char{8})失败,TakePtr(char{0})没有。
标签: c++ c++14 c++17 visual-c++-2017