我在我的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上对此进行了测试并且效果很好,但是当我使用gcc(5.1)在Linux上编译它时,我收到以下警告:
main.cpp:22:24: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'icon' [-Wformat=]
printf("%s", smiley);
当我运行它时,我在vfprintf
内部出现了一个seg错误,因为它没有使用我提供的强制转换运算符。
我知道当我将图标传递给GUI库(具有以下原型(const char* fmt, ...)
时,我可以显式地转换图标,但这会让我写更多的代码,而且看起来会更糟。
有没有办法让编译器发挥魔力并允许我调用这样的函数:printf("%s", smiley);
(或其他一些简单的方法)?
答案 0 :(得分:5)
C ++没有很好地处理Varargs函数。最重要的是,没有隐式的对象转换,因为编译器不能(在一般情况下)知道实际期望的类型。
如果有替代方法,最好的解决方案是不使用vararg函数。对于printf
和朋友(printf
它是std::cout
)。
如果由于某种原因仍然需要使用vararg函数(例如,因为您使用C库),那么唯一的解决方案是显式地转换对象。在您的情况下,它将是static_cast<const char*>(smiley)
。