简体   繁体   English

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

[英]C++ user-defined conversion operators without classes?

In C++ is it possible to define conversion operators which are not class members? 在C ++中是否可以定义非类成员的转换运算符? I know how to do that for regular operators (such as +), but not for conversion operators. 我知道如何为常规运算符(例如+)执行此操作,但不知道如何为转换运算符执行此操作。

Here is my use case: I work with a C Library which hands me out a PA_Unichar * , where the library defines PA_Unichar to be a 16-bit int. 这是我的用例:我使用的是C库, PA_Unichar *交给我,其中库将PA_Unichar定义为16位int。 It is actually a string coded in UTF-16. 它实际上是一个用UTF-16编码的字符串。 I want to convert it to a std::string coded in UTF-8. 我想将它转换为以UTF-8编码的std::string I have all the conversion code ready and working, and I am only missing the syntactic sugar that would allow me to write: 我已准备好所有转换代码并且正在工作,我只缺少允许我编写的语法糖:

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

(usually in one line without the temp variable). (通常在没有临时变量的一行中)。

Also worth noting: 另外值得注意的是:

  • I know that std::string doesn't define implicit conversion from char* and I know why. 我知道std::string没有定义来自char*隐式转换,我知道为什么。 The same reason might apply here, but that's beside the point. 同样的原因可能适用于此,但这不是重点。

  • I do have a ustring , subclass of std::string that defines the right conversion operator from PA_Unichar* . 我有一个ustringstd::string子类,它定义了PA_Unichar*的正确转换运算符。 It works but this means using ustring variables instead of std::string and that then requires conversion to std::string when I use those strings with other libraries. 它可以工作,但这意味着使用ustring变量而不是std::string然后当我将这些字符串与其他库一起使用时,需要转换为std::string So that doesn't help very much. 所以这并没有多大帮助。

  • Using an assignment operator doesn't work as those must be class members. 使用赋值运算符不起作用,因为它们必须是类成员。

So is it possible to define implicit conversion operators between two types you don't control (in my case PA_Unichar* and std::string ), which may or may not be class types? 那么可以在两个你不能控制的类型(在我的例子中是PA_Unichar*std::string )之间定义隐式转换运算符,它们可能是也可能不是类类型?

If not what could be workarounds? 如果不是什么可以解决?

What's wrong with a free function? 免费功能有什么问题?

std::string convert(PA_Unichar *libOutput);

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

Edit answering to the comment: 编辑回复评论:

As DrPizza says : Everybody else is trying to plug the holes opened up by implicit conversions through replacing them with those explicit conversion which you call "visual clutter". 正如DrPizza所说 :其他人都试图通过隐式转换来填补漏洞,用你称之为“视觉混乱”的显式转换替换它们。

As to the temporary string: Just wait for the next compiler version. 至于临时字符串:只需等待下一个编译器版本。 It's likely to come with rvalue references and its std::string implementation will implement move semantics on top of that, which eliminates the copy. 它可能带有rvalue引用,它的std::string实现将在其上实现移动语义,从而消除了副本。 I have yet to see a cheaper way to speedup your code than than by simply upgrading to a new compiler version. 我还没有看到一种更便宜的加速代码的方法,而不仅仅是升级到新的编译器版本。

Implicit conversions are the devil, anyway. 无论如何,隐含的转换是魔鬼。 Make it explicit with a converting function call. 使用转换函数调用使其显式化。

I don't think you can define "global" conversion operators. 我不认为你可以定义“全局”转换运算符。 The standards say that conversion functions are special member functions . 标准说conversion functionsspecial member functions I would propse the following if I could consider the following syntax sugar: 如果我可以考虑以下语法糖,我会提出以下建议:

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

Be aware that polymorphic behavior of this class is broken. 请注意,此类的多态行为已被破坏。 As long as you don't create an object of it through a pointer of type string* though, you are in the safe-side! 只要你不通过string*类型的指针创建它的对象,你就是安全的! So, this code is perfect: 所以,这段代码是完美的:

mystring str(....);

As said before, the following code is broken! 如前所述,以下代码被破坏了!

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

No, you can't. 不,你不能。 What you could do as an alternative is to create a conversion constructor in the target class (not your case, as you want to convert to std::string - unless you derive it). 你可以做的另一种方法是在目标类中创建一个转换构造函数(不是你的情况,因为你想转换为std :: string - 除非你派生它)。 But I agree to the other answers, I think an implicit conversion is not recommended in this case - especially because you're not converting from an object but from a pointer. 但我同意其他答案,我认为在这种情况下不建议使用隐式转换 - 特别是因为您不是从对象转换而是从指针转换。 Better to have a free function, your code will be easier to understand and the next programmer to inherit the code will for sure thank you. 最好有一个免费的功能,你的代码将更容易理解,下一个继承代码的程序员肯定会感谢你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM