8

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

这是我的用例:我使用一个 C 库,它给我一个PA_Unichar *,其中库将 PA_Unichar 定义为 16 位 int。它实际上是一个以 UTF-16 编码的字符串。我想将其转换为std::stringUTF-8 编码。我已经准备好所有的转换代码并且可以工作了,我只是缺少可以让我编写的语法糖:

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

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

另外值得注意的是:

  • 我知道这std::string没有定义隐式转换char*,我知道为什么。相同的原因可能适用于此,但这无关紧要。

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

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

那么是否可以在您无法控制的两种类型(在我的情况下为PA_Unichar*std::string)之间定义隐式转换运算符,它们可能是也可能不是类类型?

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

4

4 回答 4

9

免费功能有什么问题?

std::string convert(PA_Unichar *libOutput);

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

编辑对评论的回答:

正如DrPizza 所说:其他人都试图通过用那些你称之为“视觉混乱”的显式转换来替换隐式转换打开的漏洞。

至于临时字符串:等待下一个编译器版本。它可能带有右值引用,并且它的std::string实现将在此之上实现移动语义,从而消除了副本。我还没有看到比简单地升级到新的编译器版本更便宜的方法来加速你的代码。

于 2009-10-24T13:59:37.980 回答
5

无论如何,隐式转换是魔鬼。使用转换函数调用使其明确。

于 2009-10-24T19:22:57.733 回答
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
于 2009-10-24T14:09:10.327 回答
3

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

于 2009-10-24T21:11:34.707 回答