[英]C++ Implicit Conversion Operators Precedence
EDIT: Following Mike Seymour's comment, I replaced operator std::string () const;
编辑:在迈克·西摩的评论后,我替换了operator std::string () const;
with operator char * () const;
使用operator char * () const;
and changed the implementation accordingly. 并相应地更改了实现。 This allows implicit casting, but, for some reason, the unsigned long int operator has precedence over the char * operator, which just does not feel right... Also, I don't want to expose nasty C stuff like char * outside the class, when I have std::string. 这允许隐式强制转换,但是由于某种原因,unsigned long int运算符的优先级高于char *运算符,这感觉不对。。而且,我不想在类,当我有std :: string时。 I have a hunch that my CustomizedInt class needs to inherit from some stuff in order to support the feature that I desire. 我有一个预感,我的CustomizedInt类需要从某些东西继承来支持我想要的功能。 Could anybody please elaborate Mike's comment regarding std::basic_string
? 有人可以详细说明Mike关于std::basic_string
的评论吗? I'm not sure I understood it properly. 我不确定我是否理解正确。
I have this piece of code: 我有这段代码:
#include <string>
#include <sstream>
#include <iostream>
class CustomizedInt
{
private:
int data;
public:
CustomizedInt() : data(123)
{
}
operator unsigned long int () const;
operator std::string () const;
};
CustomizedInt::operator unsigned long int () const
{
std::cout << "Called operator unsigned long int; ";
unsigned long int output;
output = (unsigned long int)data;
return output;
}
CustomizedInt::operator std::string () const
{
std::cout << "Called operator std::string; ";
std::stringstream ss;
ss << this->data;
return ss.str();
}
int main()
{
CustomizedInt x;
std::cout << x << std::endl;
return 0;
}
Which prints "Called operator unsigned long int; 123". 其中显示“ Called operator unsigned long int; 123”。 My questions are these: 我的问题是:
After I remove the operator unsigned long int, why do I need to cast x to std::string explicitly? 删除运算符unsigned long int后,为什么需要将x强制转换为std :: string? Why does it not call the implicit cast operator (std::string) directly? 为什么不直接调用隐式强制转换运算符(std :: string)?
The version of <<
for strings is a template, parametrised by the parameters of the std::basic_string
template ( std::string
itself being a specialisation of that template). 字符串的<<
版本是一个模板,由std::basic_string
模板的参数设置参数( std::string
本身是该模板的一种特殊形式)。 It can only be chosen by argument-dependent lookup, and that only works if the argument is actually a specialisation of std::basic_string
, not something convertible to that. 它只能通过依赖于参数的查找来选择,并且仅在参数实际上是std::basic_string
而不是可转换的东西时才起作用。
Is there any documentation that explains which implicit casts are allowed and which is their order of precedence? 是否有任何文档说明允许哪些隐式强制转换及其优先顺序?
The rules are quite complex, and you'd need to read the C++ standard for the full story. 规则非常复杂,您需要阅读C ++标准以获取全文。 Simple rules of thumb are that implicit conversions can't contain more than one user-defined conversion and (as you've found out) the result of an implicit conversion can't be used to choose a template specialisation by argument-dependent lookup. 简单的经验法则是,隐式转换不能包含多个用户定义的转换,并且(如您所知),隐式转换的结果不能用于通过依赖于参数的查找来选择模板特化。
I am not sure I fully understand the associated caveats. 我不确定我是否完全理解相关的警告。 Could somebody please outline them? 有人可以概述一下吗?
I don't fully understand them either; 我也不完全理解它们。 the interactions between implicit conversions, name lookup and template specialisation (and probably other factors that I can't think of right now) are rather complex, and most people don't have the inclination to learn them all. 隐式转换,名称查找和模板专业化之间的相互作用(可能还有我现在无法想到的其他因素)非常复杂,并且大多数人都不愿意全部学习它们。 There are quite a few instances where implicit conversion won't happen, and others where it might happen when you don't expect it; 在很多情况下不会发生隐式转换,而在其他情况下可能会在您不期望的情况下发生。 personally, I find it easier just to avoid implicit conversions most of the time. 就个人而言,我发现在大多数情况下避免隐式转换会更容易。
Would it be better practice to just define public methods ToUnsignedLongInt and ToString? 仅定义公共方法ToUnsignedLongInt和ToString是否是更好的做法?
That's probably a good idea, to avoid unwanted conversions. 避免不必要的转换可能是个好主意。 You can fix your problem by leaving them and use them explicitly when necessary: 您可以通过留下问题来解决问题,并在必要时明确使用它们:
std::cout << std::string(x) << std::endl;
In C++11, you can declare them explicit
, so that they can only be used in this manner. 在C ++ 11中,可以将它们声明为explicit
,因此只能以这种方式使用它们。 In my opinion, that would be the best option if you can; 我认为,这将是最好的选择。 otherwise, I would use explicit conversion functions as you suggest. 否则,我将按照您的建议使用显式转换函数。
By the way, the return type of main()
must be int
, not void
. 顺便说一句, main()
的返回类型必须是int
,而不是void
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.