2010-05-25 61 views
2

爲了方便起見,我希望能夠在其他庫中定義的兩種類型之間進行轉換。 (具體QString從ICU庫Qt庫和UnicodeString)項目中的命名空間現在,我已經創建了實用功能:其他庫中的類型之間的C++轉換運算符

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

這一切都很好,但我想知道如果有一個更優雅的方式。理想情況下,我希望能夠使用投射算子在它們之間進行轉換。然而,我確實希望保留轉換的明確性質。隱式轉換不應該是可能的。

有沒有更好的方法來實現這一點,而無需修改庫的源代碼?可能有一些運算符重載語法?

回答

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); 

我不知道這種方法的優雅雖然與你的兩個顯式轉換函數相比較。

+0

謝謝;我只是好奇,如果有什麼我失蹤的語言。看起來像原來的方式是儘可能簡單,你可以得到。 – 2010-06-02 15:15:50

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

編輯:過來想一想,我正在做我在我的項目之一中從std :: string轉換爲/從std :: wstring。我想我會用這個替代方案來取代它。

0

一個可能的解決方案是包裝這些類型並提供顯式的轉換構造函數。我認爲你不能修改QStringicu_44::UnicodeString的來源,這將是轉換構造函數駐留的最自然的地方。關鍵字explicit的使用禁止了隱式轉換,因此轉換隻能在您編寫QString converted(original)original類型爲icu_44::UnicodeString的值時發生,反之亦然。

這種方法唯一的問題是你必須包裝你的數據類型。我不知道你是否需要在目前沒有提供的實際庫中使用這些類型的更多操作,但是如果是這種情況,換行是一種可行的方法。

0

旁邊的問題,你的意思是直接使用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

相關問題