【问题标题】:Force `const char[]` string literals in clang在 clang 中强制使用 `const char[]` 字符串文字
【发布时间】:2015-08-15 11:12:08
【问题描述】:

编译如下代码

void f(char *, const char *, ...) {}
void f(const char *, ...) {}

int main()
{
    f("a", "b");
}

with clang 给了我这个错误:

prog.cpp:6:2: error: call to 'f' is ambiguous
        f("a", "b");
        ^
prog.cpp:1:6: note: candidate function
void f(char *, const char *, ...) {}
     ^
prog.cpp:2:6: note: candidate function
void f(const char *, ...) {}
     ^

AFAIK 字符串字面量在 C++ 中是常量,因此重载规则应该不考虑第一个变体,从而明确解析为第二个变体。但我猜 Clang 出于兼容性原因将它们设为非 const(我知道 MSVC 也这样做)。

使用什么编译器标志来解决这个问题?我已经在用-std=c++11 编译了。

编辑:显式转换为const char* 解决了这个问题:

    f((const char*)"a", "b");

但如果我对观察到的编译器行为不标准是正确的,我想修复编译器行为而不是标准符合代码。

【问题讨论】:

  • @Jarod42:因为我喜欢这个名字。如果代码没有被破坏,那么我认为“修复”它不是正确的解决方案。
  • 我前段时间搜索了一个编译器开关来停用这种可怕的转换为char*,但找不到任何东西。至少,没有记录在案。是时候加一个了,我猜?顺便说一句,MSVC 有一些“严格的字符串”开关。
  • 嘿,我刚刚想出了完全相同的 MCVE 字符...
  • @davmac 如果允许转换为char * 会很模糊
  • @MattMcNabb 我只是在复制编译器输出的内容,这不是 我的 解释,它是 GCC。

标签: c++ c++11 clang string-literals overload-resolution


【解决方案1】:

我认为这是一个错误。在 C++11 中删除了将字符串文字转换为 char * 的功能,我不知道在重载决议中针对涉及它的转换序列有任何规定。

作为一种不涉及将每个调用都更改为f 的解决方法,您可以编写另一个重载,通过引用捕获数组来使用字符串文字显式捕获每个调用:

template<size_t N, typename ...F>
void f(char const (&a)[N], F&&... args)
{
    f((char const *)a, std::forward<F>(args)...);
}

【讨论】:

  • 糟糕的是,现在[[gnu::format(printf, 1, 2)]] 不起作用:(
  • 这是正确答案!根据标准:窄字符串文字的类型为“n const char 数组”。
  • @ybungalobill Argh,也许还有另一种方法可以让您继续使用它。
猜你喜欢
  • 2020-01-03
  • 2021-10-15
  • 1970-01-01
  • 2021-12-26
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
相关资源
最近更新 更多