字符串文字绑定到非const char指针

时间:2017-10-24 19:46:08

标签: c++ c++11

考虑以下计划:

#include <iostream>

void myprint(const char* fmt, ...)
{
  std::cout << "1 ";
}

void myprint(const char* fmt, char *x)
{
  std::cout << "2 ";
}

int main()
{
  const char* s = "c";
  myprint("a", s);
  myprint("a", "b");
}

它产生不同的输出:

我的问题是双重的:

  1. 为什么即使存在char*,字符串文字也会绑定到非const -std=c++14?从C ++ 11开始,它不是字符串文字const吗?

  2. 省略号过载始终排在最低位置。为什么clang选择它? (人们会认为它不允许绑定到char*但是如果我删除省略号重载,它仍然会 - demo

  3. 发生了什么事,谁是对的?

1 个答案:

答案 0 :(得分:2)

  

为什么即使存在char*,字符串文字也会绑定到非const -std=c++14

这是一个已弃用的转换,已从C ++ 11开始正式删除。

  

自C ++ 11以来,Isn不是字符串文字const吗?

不,字符串文字一直是const

  

省略号过载总是排名最低。 clang为什么选择它?

因为另一个无效。没有const char*char*的转换,原因与无法将const std::string&转换为std::string&的原因相同。

因此,重载决策会跳过一个并选择唯一剩余的重载(也恰好有效),并打印1

  

有人会认为它不允许绑定到char *但是如果我删除省略号重载,它仍然会

是的,这是一个非标准扩展,就像gcc一样。您应该尝试使用-pedantic进行编译。

  

发生了什么事,谁是对的?

铿锵绝对是对的。不允许扩展来修改格式良好的C ++程序([intro.compliance]p8)的行为,因此gcc和MSVC使用第二次重载是错误的,因为标准不支持来自{{{{{}的隐式转换。 1}}到const char*,因此应该回到第一个。

重申一下,您的演示符合标准,因为该程序根据标准(字符串转换)格式不正确并且它们发出诊断信息,因此它不会与链接的段落发生冲突上方。