为方便起见,我希望能够在其他库中定义的两种类型之间进行转换。 (具体来说,来自Qt库的QString
和来自ICU库的UnicodeString
。)现在,我已在项目命名空间中创建了实用程序函数:
namespace MyProject {
const icu_44::UnicodeString ToUnicodeString(const QString& value);
const QString ToQString(const icu_44::UnicodeString& value);
}
这一切都很好,但我想知道是否有更优雅的方式。理想情况下,我希望能够使用强制转换运算符在它们之间进行转换。但是,我确实希望保留转换的明确性质。不应该进行隐式转换。
有没有更优雅的方法来实现这一点而不修改库的源代码?一些运算符重载语法,也许?
答案 0 :(得分:7)
你可以随时做你正在做的事,但让它看起来更像是施法。这样做甚至可能有一些合理的论据,例如能够覆盖更多类型并保留相同的语法。
考虑:
template < typename DestType, typename SourceType >
DestType string_cast(SourceType const& source)
{
return string_cast_impl<DestType,SourceType>::apply(source);
}
template < typename DestType, typename SourceType >
struct string_cast_impl;
template < >
struct string_cast_impl<QString,icu_44::UnicodeString>
{
QString apply(icu_44::UnicodeString const& val) { return MyProject::ToQString(value); }
};
// etc...
您可能考虑不使用impl结构(因为您不需要部分专门化...),或者您可以考虑对其进行增强,以便您可以使用enable_if。无论如何,你有一个用于字符串类型转换的通用接口,这样你就不需要记住要调用的函数了......只需调用string_cast&lt; Dest&gt;(source)。
编辑:想一想,我正在做我正在做的事情,从std :: string转换为std :: wstring。我想我会用这个替代品替代它。
答案 1 :(得分:2)
如果你所追求的是能够说出
QStrign qs;
UnicodeString us(qs);
或
UnicodeString us;
QString qs(us);
然后不,你不能这样做,除非你可以改变任何一个类。当然,您可以引入一个新字符串:
NewString ns;
UnicodeString us(ns);
QString qs(us);
NewString nsus(us);
NewString nsqs(qs);
与你的两个显式转换函数相比,我不确定这种方法的优雅。
答案 2 :(得分:0)
一种可能的解决方案是包装这些类型并提供显式转换构造函数。我认为你不能修改QString
和icu_44::UnicodeString
的来源,这将是转换构造函数驻留的最自然的地方。关键字explicit
的使用禁止隐式转换,因此只有在QString converted(original)
original
写icu_44::UnicodeString
类型的值时才能进行转换,反之亦然。
此方法的唯一问题是您必须包装数据类型。我不知道你是否需要对目前未在实际库中提供的这些类型进行更多操作,但如果是这种情况,包装是一种可行的方法
答案 3 :(得分:0)
附带问题,您是指直接使用4.4命名空间而不仅仅是icu :: UnicodeString?