C ++隐式转换运算符优先级 [英] C++ Implicit Conversion Operators Precedence

查看:234
本文介绍了C ++隐式转换运算符优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:按照Mike Seymour的注释,我替换运算符std :: string()const; code>并相应地更改了实现。这允许隐式转换,但是,由于某种原因,unsigned long int运算符优先于char *运算符,这是不正确的...此外,我不想暴露讨厌的C的东西,如char *外面类,当我有std :: string。我有一个希望,我的CustomizedInt类需要继承一些东西,以支持我想要的功能。任何人请详细说明Mike关于 std :: basic_string 的意见?我不确定我是否理解正确。

Following Mike Seymour's comment, I replaced operator std::string () const; with 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. I have a hunch that my CustomizedInt class needs to inherit from some stuff in order to support the feature that I desire. Could anybody please elaborate Mike's comment regarding std::basic_string? I'm not sure I understood it properly.

我有这条代码:

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

这里输出Called operator unsigned long int; 123。我的问题是这些:

Which prints "Called operator unsigned long int; 123". My questions are these:


  1. 在我删除运算符unsigned long int之后,为什么需要显式地将x转换为std :: string?为什么不直接调用隐式转换运算符(std :: string)?

  2. 是否有任何文档解释允许哪些隐式转型,以及它们的优先级顺序?看起来如果我把一个运算符unsigned int和运算符unsigned long int一起添加到这个类中,我会收到一个关于<< operator ...

  3. 此外,我知道定义这样的运算符可能是不好的做法,但我不能确定我是否完全理解相关的警告。有人请大概说一下吗?是否更好的做法是只定义公共方法ToUnsignedLongInt和ToString?


推荐答案


在我删除运算符unsigned long int之后,为什么需要显式地将x转换为std :: string?为什么不直接调用隐式转换运算符(std :: string)?

After I remove the operator unsigned long int, why do I need to cast x to std::string explicitly? Why does it not call the implicit cast operator (std::string) directly?

; 对于字符串是一个模板,由 std :: basic_string 模板参数( std :: string 本身是该模板的特殊化)。它只能通过参数相关的查找来选择,并且只有当参数实际上是 std :: basic_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). 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.


是否有任何文档解释哪些隐式转型是允许的,哪些是它们的优先顺序?

Is there any documentation that explains which implicit casts are allowed and which is their order of precedence?

规则相当复杂,你需要阅读完整故事的C ++标准。简单的经验法则是,隐式转换不能包含多个用户定义的转换,并且(如您所知),隐式转换的结果不能用于通过参数相关查找来选择模板专用化。

The rules are quite complex, and you'd need to read the C++ standard for the full story. 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.


更好的做法是只需定义公共方法ToUnsignedLongInt和ToString?

Would it be better practice to just define public methods ToUnsignedLongInt and 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;

在C ++ 11中,可以声明 explicit ,因此它们只能以这种方式使用。在我看来,这将是最好的选择,如果你可以;

In C++11, you can declare them explicit, so that they can only be used in this manner. In my opinion, that would be the best option if you can; otherwise, I would use explicit conversion functions as you suggest.

顺便说一下, main()的返回类型必须 int ,而不是 void

By the way, the return type of main() must be int, not void.

这篇关于C ++隐式转换运算符优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆