为什么 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*

现在,如果我同时拥有 charchar* 重载,它可以正常工作而不会出现任何 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{} 意思相同,尽管它从未与规则重叠。