没有类的C ++用户定义转换运算符?

时间:2009-10-24 13:40:51

标签: c++ operator-overloading coercion

在C ++中是否可以定义非类成员的转换运算符?我知道如何为常规运算符(例如+)执行此操作,但不知道如何为转换运算符执行此操作。

这是我的用例:我使用的是一个C库,它向我发送PA_Unichar *,其中库将PA_Unichar定义为16位int。它实际上是一个用UTF-16编码的字符串。我想将其转换为以UTF-8编码的std::string。我已经准备好了所有转换代码并且正在工作,我只是错过了允许我写的语法糖:

PA_Unichar *libOutput = theLibraryFunction();
std::string myString = libOutput;

(通常在没有临时变量的一行中)。

另外值得注意的是:

  • 我知道std::string没有定义char*的隐式转换,我知道原因。同样的原因可能适用于此,但这不是重点。

  • 我有一个ustringstd::string的子类,它定义了PA_Unichar*的正确转换运算符。它有效,但这意味着使用ustring变量而不是std::string,当我将这些字符串与其他库一起使用时,然后需要转换为std::string。所以这没有多大帮助。

  • 使用赋值运算符不起作用,因为必须是类成员。

那么可以在两个你不能控制的类型(在我的例子中是PA_Unichar*std::string)之间定义隐式转换运算符,它们可能是也可能不是类类型?

如果不是什么可以解决方法?

4 个答案:

答案 0 :(得分:8)

免费功能有什么问题?

std::string convert(PA_Unichar *libOutput);

std::string myString = convert(theLibraryFunction());

编辑回复评论:

作为DrPizza says:其他人正在尝试通过隐式转换来填充漏洞,将其替换为您称之为“视觉混乱”的显式转换。

关于临时字符串:只需等待下一个编译器版本。它可能带有右值引用,它的std::string实现将在其上实现移动语义,从而消除了副本。我还没有看到一种更便宜的加速代码的方法,而不仅仅是升级到新的编译器版本。

答案 1 :(得分:5)

无论如何,隐含的转换都是魔鬼。使用转换函数调用使其显式化。

答案 2 :(得分:4)

我认为您无法定义“全局”转换运算符。标准说conversion functionsspecial member functions。如果我可以考虑以下语法糖,我会提出以下建议:

struct mystring : public string
{
    mystring(PA_Unichar * utf16_string)
    {
        // All string functionality is present in your mystring.
        // All what you have to do is to write the conversion process.
        string::operator=("Hello World!");
        string::push_back('!');
        // any string operation...
    }
};

请注意,此类的多态行为已被破坏。只要你不通过string*类型的指针创建它的对象,你就是安全的!所以,这段代码是完美的:

mystring str(....);

如前所述,以下代码已被破坏!

string* str = new mystring(....);
....
delete str; // only deleting "string", but not "mystring" part of the object
// std::string doesn't define virtual destructor

答案 3 :(得分:3)

不,你不能。你可以做的另一种方法是在目标类中创建一个转换构造函数(不是你的情况,因为你想转换为std :: string - 除非你派生它)。但我同意其他答案,我认为在这种情况下不建议使用隐式转换 - 特别是因为您不是从对象转换而是从指针转换。最好有一个免费的功能,你的代码将更容易理解,下一个继承代码的程序员肯定会感谢你。