其他分享
首页 > 其他分享> > C隐式转换运算符优先级

C隐式转换运算符优先级

作者:互联网

编辑:在Mike Seymour的评论之后,我替换了运算符std :: string()const; with operator char *()const;并相应地改变了实施.这允许隐式转换,但是,由于某种原因,unsigned long int运算符优先于char *运算符,这只是感觉不对…而且,我不想暴露讨厌的C之类的东西,比如char * class,当我有std :: string时.我有一种预感,我的CustomizedInt类需要继承一些东西才能支持我想要的功能.有人可以详细说明Mike关于std :: basic_string的评论吗?我不确定我是否理解得当.

我有这段代码:

#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”.我的问题是这些:

>我删除运算符unsigned long int后,为什么需要显式地将x转换为std :: string?为什么不直接调用隐式强制转换操作符(std :: string)?
>是否有任何文档可以解释允许哪些隐式强制转换以及哪些是优先顺序?似乎如果我将运算符unsigned int与运算符unsigned long int一起添加到此类中,我会收到有关<<<<<<<<操作符...
>此外,我知道定义这样的运算符可能是不好的做法,但我不确定我是否完全理解相关的警告.有人可以概述一下吗?将公共方法ToUnsignedLongInt和ToString定义为更好的做法吗?

解决方法:

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?

<<< for strings是一个模板,由std :: basic_string模板的参数进行参数化(std :: string本身是该模板的特化).它只能通过依赖于参数的查找来选择,并且仅在参数实际上是std :: basic_string的特化时才有效,而不是可转换为std :: basic_string的特性.

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

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

I am not sure I fully understand the associated caveats. Could somebody please outline them?

我也不完全理解他们;隐式转换,名称查找和模板特化(以及可能是我现在无法想到的其他因素)之间的相互作用相当复杂,而且大多数人并不倾向于全部学习它们.有很多情况下隐式转换不会发生,而其他情况可能会发生在您不期望的情况下;就个人而言,我发现在大多数情况下避免隐式转换更容易.

Would it be better practice to just define public methods ToUnsignedLongInt and ToString?

这可能是一个好主意,以避免不必要的转换.您可以通过保留问题来解决问题,并在必要时明确使用它们:

std::cout << std::string(x) << std::endl;

在C 11中,您可以将它们声明为显式,以便它们只能以这种方式使用.在我看来,如果可以,这将是最好的选择;否则,我会按照你的建议使用显式转换函数.

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

标签:conversion-operator,c,casting,operator-precedence
来源: https://codeday.me/bug/20191007/1868287.html