【问题标题】:Implicit cast to char* when calling printf调用 printf 时隐式转换为 char*
【发布时间】:2018-01-04 08:57:57
【问题描述】:

我在我的 C++ GUI 应用程序中使用 Unicode 字符串作为图标,并希望摆脱我散落的所有 u8"\uf118" 魔术字符串,并在途中使这些字符串成为自己的类型。

所以我创建了一个这样的类:

struct icon
{
    explicit constexpr icon(const char (&unicode_icon)[4]) :
        _icon{ unicode_icon[0], unicode_icon[1], unicode_icon[2], unicode_icon[3] }
    {
    }
    operator const char*() const
    {
        return _icon.data();
    }
private:
    std::array<char, 5> _icon;
};

GUI 库使用某种形式的printf(我认为是vfprintf) 所以代码调用:

icon smiley { u8"\uf118" };
printf("%s", smiley);

到目前为止,我在 Windows 上对此进行了测试,效果很好,但是当我在 Linux 上使用 gcc (5.1) 编译它时,我收到以下警告:

main.cpp:22:24: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'icon' [-Wformat=]
     printf("%s", smiley);

Live example here

当我运行它时,我在vfprintf 中遇到了一个段错误,因为它没有使用我提供的强制转换运算符。

我知道当我将图标传递给 GUI 库时我可以显式地转换它(它具有以下原型 (const char* fmt, ...) 但这会让我编写更多代码,而且看起来会更糟。

有没有办法让编译器发挥作用并允许我像这样调用函数:printf("%s", smiley);(或其他一些简单的方法)?

【问题讨论】:

  • 嗯,为什么?为什么需要上课?为什么不const char* smiley = u8"\uf118";
  • 如果它在 Windows 上工作,那只是一个意外,明天不一定能工作。
  • 或者,在紧要关头,const std::string smiley{u8"\uf118"}; 这些东西毕竟是字符串。
  • printf() 是一个可变参数函数。格式说明符告诉函数如何解释它接收到的相应参数。它不会告诉编译器为了将对象作为参数传递而转换为指定的类型。
  • @n.m. const std::string smiley 将运行时开销添加到以前只是 printf("%s", u8"\uf118") 的代码中

标签: c++ c++11 gcc printf variadic-functions


【解决方案1】:

C++ 不能很好地处理可变参数函数。最重要的是,没有隐式转换对象,因为编译器(在一般情况下)无法知道真正期望的类型。

如果有替代方案,最好的解决方案是使用可变参数函数。对于printf 和朋友,有(对于printf 它是std::cout)。

如果您出于某种原因仍需要使用可变参数函数(例如因为您使用 C 库),那么唯一的解决方案是显式转换对象。在您的情况下,它将是 static_cast&lt;const char*&gt;(smiley)

【讨论】:

  • 另一个变体是有一个c_str() 成员(就像std::string 一样)。
  • Microsoft 的CString 使用char* 作为第一个成员的布局,以允许printf 在没有演员表的情况下工作,但他们也说你最好转换它以获得预期的结果 - @987654321 @
  • @A.A 这也是非常特定于实现的,并且很大程度上取决于编译器如何实现可变参数。
  • 我同意这个答案,但我还不想接受它,因为也许有人会想出一个漂亮的解决方法或其他一些简单的方法
  • 我最终为 gui 函数添加了一个重载,该函数接受 icon 并使用静态转换调用原始 API...
猜你喜欢
  • 2012-11-15
  • 1970-01-01
  • 2013-10-05
  • 2015-01-01
  • 2011-10-24
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
相关资源
最近更新 更多