Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ conversion operator between types in other libraries

Tags:

c++

casting

For convenience, I'd like to be able to cast between two types defined in other libraries. (Specifically, QString from the Qt library and UnicodeString from the ICU library.) Right now, I have created utility functions in a project namespace:

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

That's all well and good, but I'm wondering if there's a more elegant way. Ideally, I'd like to be able to convert between them using a cast operator. I do, however, want to retain the explicit nature of the conversion. An implicit conversion should not be possible.

Is there a more elegant way to achieve this without modifying the source code of the libraries? Some operator overload syntax, perhaps?

like image 422
Dave Mateer Avatar asked Dec 13 '25 07:12

Dave Mateer


2 Answers

You could always do exactly what you're doing but make it look more like casting. There may even be some reasonable argument for doing so, such as being able to override for more types and retain the same syntax.

Consider:

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...

You might consider not using the impl struct (because you don't need to partially specialize...ever), or you might consider enhancing it so that you can use enable_if. At any rate, you'd have a common interface for string type conversion such that you don't need to remember what function to call...just call string_cast<Dest>(source).

Edit: come to think of it, I'm doing what you're doing in one of my projects to convert from std::string to/from std::wstring. I think I'll use this alternative to replace that.

like image 92
Edward Strange Avatar answered Dec 14 '25 21:12

Edward Strange


If what you're striving for is to be able to say

QStrign qs;
UnicodeString us(qs);

or

UnicodeString us;
QString qs(us);

then no, you can't do that unless you can change either of the classes. You can, of course, introduce a new string:

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

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

I'm not sure about this approach's elegance though, compared with your two explicit conversion functions.

like image 22
wilhelmtell Avatar answered Dec 14 '25 21:12

wilhelmtell