【问题标题】:Why do char{} and char() work as a temporary variable for a char* argument?为什么 char{} 和 char() 用作 char* 参数的临时变量?
【发布时间】: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*

现在,如果我同时有 charchar* 重载,它可以正常工作而不会出现任何关于歧义的错误/警告:

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


【解决方案1】:

因为视觉谎言很多。尤其是年纪大的。你的代码提示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++ 标准方面是众所周知的,所以不要过分依赖它。尝试使用 clang/gcc 进行验证,以确保确定。

【讨论】:

    【解决方案2】:

    这只是 MSVC 落后了:C++03 中的规则是 any 整数类型和值 0 的常量表达式是一个空指针常量,因此可以转换为 char*。当然char() 符合条件,而char{} 的含义相同,尽管它从未与规则重叠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2021-09-05
      相关资源
      最近更新 更多