其他库中的类型之间的C++转换运算符

问题描述:

为了方便起见,我希望能够在其他库中定义的两种类型之间进行转换。 (具体QString从ICU库Qt库和UnicodeString)项目中的命名空间现在,我已经创建了实用功能:其他库中的类型之间的C++转换运算符

namespace MyProject { 
    const icu_44::UnicodeString ToUnicodeString(const QString& value); 
    const QString ToQString(const icu_44::UnicodeString& value); 
} 

这一切都很好,但我想知道如果有一个更优雅的方式。理想情况下,我希望能够使用投射算子在它们之间进行转换。然而,我确实希望保留转换的明确性质。隐式转换不应该是可能的。

有没有更好的方法来实现这一点,而无需修改库的源代码?可能有一些运算符重载语法?

如果你正在努力的就是能够说

QStrign qs; 
UnicodeString us(qs); 

UnicodeString us; 
QString qs(us); 

则没有,你不能这样做,除非你可以改变任何类的。你可以,当然,引入新的字符串:

NewString ns; 
UnicodeString us(ns); 
QString qs(us); 

NewString nsus(us); 
NewString nsqs(qs); 

我不知道这种方法的优雅虽然与你的两个显式转换函数相比较。

+0

谢谢;我只是好奇,如果有什么我失踪的语言。看起来像原来的方式是尽可能简单,你可以得到。 – 2010-06-02 15:15:50

你总是可以做你正在做的事情,但让它看起来更像铸造。这样做甚至可能有一些合理的理由,比如能够覆盖更多类型并保留相同的语法。

考虑:

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 < Dest>(source)。

编辑:过来想一想,我正在做我在我的项目之一中从std :: string转换为/从std :: wstring。我想我会用这个替代方案来取代它。

一个可能的解决方案是包装这些类型并提供显式的转换构造函数。我认为你不能修改QStringicu_44::UnicodeString的来源,这将是转换构造函数驻留的最自然的地方。关键字explicit的使用禁止了隐式转换,因此转换只能在您编写QString converted(original)original类型为icu_44::UnicodeString的值时发生,反之亦然。

这种方法唯一的问题是你必须包装你的数据类型。我不知道你是否需要在目前没有提供的实际库中使用这些类型的更多操作,但是如果是这种情况,换行是一种可行的方法。

旁边的问题,你的意思是直接使用4.4命名空间,而不仅仅是icu :: UnicodeString?

+0

我还没有真正想出ICU命名空间的东西。我正在编译-DU_USING_ICU_NAMESPACE = 0,但仍然可以直接引用UnicodeString(没有名称空间)在我的代码中,并且它工作正常。但我也可以使用icu_44 :: UnicodeString(但不是icu :: UnicodeString)。我正在使用icu_44 :: UnicodeString,因为可能另一个是较旧的库?不确定。仍在工作中...... – 2010-06-02 18:06:51

+0

将icu映射到icu_44是符号重命名的一项功能。如果使用-DU_DISABLE_RENAMING = 1进行编译(或使用--disable-renaming选项进行配置),则不会发生这种情况。这会影响符号。 另一个不是一个较老的图书馆。我只是在没有命名空间的情况下引用UnicodeString,并按原样保留重命名。 – 2010-06-04 19:11:22