C++用户定义的转换运算符没有类?
在C++中可以定义不是类成员的转换运算符吗?我知道如何为常规运营商(例如+)做到这一点,但不适用于转换运营商。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*
定义隐式转换,我知道这是为什么。这里也可能适用同样的理由,但那不是重点。我确实有一个
ustring
,std::string
的子类,它定义了从PA_Unichar*
正确的转换运算符。它的工作原理,但这意味着使用ustring
变量而不是std::string
,然后需要转换到std::string
时,我使用这些字符串与其他库。所以这并没有太大的帮助。使用赋值运算符不起作用,因为那些必须是是类成员。
那么,这可以定义两种类型的你不用管(在我的情况PA_Unichar*
和std::string
),这可能是也可能不是类类型之间的隐式转换运营商?
如果不是什么可能的解决方法?
自由功能有什么问题?
std::string convert(PA_Unichar *libOutput);
std::string myString = convert(theLibraryFunction());
编辑回答了评论:
由于DrPizza says:其他人都试图堵塞漏洞通过与那些你所谓的“视觉混乱”显式转换代替他们开辟的隐式转换。
至于临时字符串:只是等待下一个编译器版本。它可能带有右值引用,它的std::string
实现将在其上实现移动语义,从而消除副本。我还没有看到比简单升级到新编译器版本更便宜的方法来加速代码。
我不认为你可以定义“全局”转换运算符。标准说conversion functions
是special 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
无论如何,隐式转换是魔鬼。用转换函数调用明确它。
嗯,这取决于。存在隐式转换有意义的实际情况。例如,我通常使用它们来将一种类型转换为另一种类型,这在语义上是另一种类型的子集。例如,如果你有一个“人”类和一个“员工”,我希望'雇员'自动转换为'人',无论后者在哪里。 (当然,另一方面,隐式转换将是一个坏主意。) – Mephane 2011-02-23 10:33:12
我意识到你只是提出了一个假设的例子,但员工作为人的一个子类是一个糟糕的设计和宠物矿。 子类化用于is-a关系。看起来,员工是一个人,但实际上这只是英语语法歧义的一部分。员工不是特殊类型的人,而是一个人可以拥有的角色。这实际上是一种有关系。 – 2012-10-17 14:51:33
不,你不能。你可以做的替代方法是在目标类中创建一个转换构造函数(不是你的情况,因为你想转换为std :: string - 除非你派生它)。但我同意其他答案,我认为在这种情况下不推荐使用隐式转换 - 尤其是因为您不是从对象转换而是从指针转换。最好有一个免费的功能,你的代码会更容易理解,下一代程序员继承代码肯定会感谢你。
有什么不对?没有太多,但仍有两件事: - 视觉混乱,当你有数百个毫无意义的调用来转换 - 这个解决方案意味着使用临时的std :: string。这意味着数据总是被复制两次。这可能是也可能不是问题,但不是很令人满意。 – 2009-10-24 14:07:03
大多数编译器会优化额外的拷贝。 – rlbond 2009-10-24 15:09:52
jdmuys> rlbond是对的,RVO在实践中是常见的和真实的。你可能会阅读:http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ – Klaim 2009-10-24 15:26:25