为什么 char{} 和 char() 用作 char* 参数的临时变量?
Why do char{} and char() work as a temporary variable for a char* argument?
在 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*
重载,它可以正常工作而不会出现任何 error/warning 歧义:
void TakePtr(char*);
void TakePtr(char);
TakePtr(char{}); // Chooses 'char'
TakePtr(char()); // Chooses 'char'
为什么编译器可以将 char{}
用于 TakePtr(char*)
?
为什么在选择 better 版本时不给出 warning/error?这种行为势必会破坏现有代码。
当然,编译器不满意:
void TakePtr(char*);
char c{};
TakePtr(c);
因为视觉谎言很多。尤其是年纪大的。你的代码提示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.
众所周知,Visual 在遵循 C++ 标准方面 "wonky",所以不要过分依赖它。尝试用 clang / gcc 验证,只是为了确定。
这只是 MSVC 的落后:C++03 中的规则是 any 整数类型和值 0 的常量表达式是空指针常量,因此可以转换至 char*
。当然 char()
符合条件——和 char{}
意思相同,尽管它从未与规则重叠。
在 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*
重载,它可以正常工作而不会出现任何 error/warning 歧义:
void TakePtr(char*);
void TakePtr(char);
TakePtr(char{}); // Chooses 'char'
TakePtr(char()); // Chooses 'char'
为什么编译器可以将 char{}
用于 TakePtr(char*)
?
为什么在选择 better 版本时不给出 warning/error?这种行为势必会破坏现有代码。
当然,编译器不满意:
void TakePtr(char*);
char c{};
TakePtr(c);
因为视觉谎言很多。尤其是年纪大的。你的代码提示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.
众所周知,Visual 在遵循 C++ 标准方面 "wonky",所以不要过分依赖它。尝试用 clang / gcc 验证,只是为了确定。
这只是 MSVC 的落后:C++03 中的规则是 any 整数类型和值 0 的常量表达式是空指针常量,因此可以转换至 char*
。当然 char()
符合条件——和 char{}
意思相同,尽管它从未与规则重叠。