简体   繁体   English

用户定义类型的隐式类型转换

[英]Implicit type conversion for user-defined type

Why is implicit type conversion not performed for user-defined type in the following source code?为什么在下面的源代码中没有对用户定义的类型进行隐式类型转换?

An implicit type conversion to type A should occur on the commented line, but it did not happen and an error occurred on that line.到类型 A 的隐式类型转换应该发生在注释行上,但它没有发生,并且在该行上发生了错误。

I would like to know the grammatical rules and solutions for this error.我想知道这个错误的语法规则和解决方法。

#include <iostream>

using namespace std;

class A {
   int v;
public:
    A(int _v): v(_v) {}
    operator int (void) const {
        return v;
    }
    friend ostream& operator << (ostream& os, const A& s) {
        return os << "A: " << s.v;
    }   
};

class B {
    int x, y;   
public:
    B(int _x, int _y): x(_x), y(_y) {}
    operator A(void) const {
        return A(x+y);
    }
};

int main(void)
{
    B b(1,2);
    cout << A(b) << endl;
    cout << (A)b << endl;
    cout << b << endl;     // error --> why?
    return 0;
}

--> Additional Question --> 附加问题

Thanks for Sam Varshavchik's reply .感谢 Sam Varshavchik 的回复。

Defining class A as below solves the problem.如下定义类 A 解决了这个问题。

class A {
   int v;
public:
    A(int _v): v(_v) {}
    operator int (void) const {
        return v;
    }
    friend ostream& operator << (ostream& os, const A& s);
};

ostream& operator << (ostream& os, const A& s){
    return os << "A: " << s.v;
}

//////////////

class A {
   int v;
public:
    A(int _v): v(_v) {}
    operator int (void) const {
        return v;
    }
    friend ostream& operator << (ostream& os, const A& s){
        return os << "A: " << s.v;
    }
};

ostream& operator << (ostream& os, const A& s);

Whether or not to declare "operator <<" as a friend doesn't seem to matter here.是否将“operator <<”声明为朋友在这里似乎并不重要。 Since the function is a global function, it can be referenced in other classes or other funcitons.由于该函数是全局函数,因此可以在其他类或其他函数中引用。 I think it matters whether the block defining the function is inside or outside class A. Why is function declaration necessary when using inner definition?我认为定义函数的块是在类 A 内部还是外部很重要。为什么使用内部定义时需要函数声明? I want to know the grammatical basis.我想知道语法基础。

This must have something to do with arcane rules related to the relationship between overload resolution, friend functions, and implicit conversions.这一定与与重载解析、友元函数隐式转换之间的关系相关的神秘规则有关。 Because this is not just about implicit conversions, here.因为这里不仅仅是隐式转换。 You're also defining an overload operator<< that's a friend function.您还定义了一个重载operator<< ,这是一个友元函数。

By simply getting rid of the friend function, the following code compiles fine, on gcc 9.2.通过简单地去掉友元函数,下面的代码在 gcc 9.2 上编译得很好。 It also doesn't hurt to get rid of using namespace std; 摆脱using namespace std;也没有坏处using namespace std; , as well : ,以及

#include <iostream>

class A {
   int v;
public:
    A(int _v): v(_v) {}
    operator int (void) const {
        return v;
    }
};

std::ostream& operator << (std::ostream& os, const A& s) {
    return os << "A: " << (int)s;
}

class B {
    int x, y;
public:
    B(int _x, int _y): x(_x), y(_y) {}
    operator A(void) const {
        return A(x+y);
    }
};

int main(void)
{
    B b(1,2);
    std::cout << A(b) << std::endl;
    std::cout << (A)b << std::endl;
    std::cout << b << std::endl;     // No more error
    return 0;
}

When a friend function is defined inside a class it will only be found through ADL.当在类中定义友元函数时,它只能通过 ADL 找到。

In your first two lines you are providing an A , so ADL kicks in and finds the operator<< .在前两行中,您提供了一个A ,因此 ADL 开始并找到operator<< When passing a B ADL will not help find your operator<< so a conversion is never considered by the compiler.传递B ADL 将无助于找到您的operator<<因此编译器永远不会考虑转换。

Some more details on ADL .关于ADL 的更多细节。

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

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