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

C++ 用户定义类型的隐式类型转换,c++,types,implicit,user-defined,C++,Types,Implicit,User Defined,为什么在下面的源代码中没有对用户定义的类型执行隐式类型转换 到类型A的隐式类型转换应该发生在注释行上,但是没有发生,并且在该行上发生了错误 我想知道这个错误的语法规则和解决方法 #include <iostream> using namespace std; class A { int v; public: A(int _v): v(_v) {} operator int (void) const { return v; }

为什么在下面的源代码中没有对用户定义的类型执行隐式类型转换

到类型A的隐式类型转换应该发生在注释行上,但是没有发生,并且在该行上发生了错误

我想知道这个错误的语法规则和解决方法

#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;
}
#包括
使用名称空间std;
甲级{
INTV;
公众:
A(int_v):v(_v){}
运算符int(void)const{
返回v;
}

friend ostream&operator这一定与重载解析、friend函数、隐式转换之间关系的神秘规则有关。因为这里不仅仅是隐式转换。当在cl中定义friend函数时,您还定义了重载
运算符只有通过ADL才能找到它


在您的前两行中,您提供了一个
A
,因此ADL将开始并找到
操作符,或者查看您要到的地方,您可能已经知道了这一点,但对于未来的读者,请注意C样式的转换
(A)b
。C风格的演员将威胁
b
作为
A
,无论它是否合理。在这里它是有意义的。它并不总是。这将是一个好地方,让
静态演员
静态演员
确保演员有意义。错误消息是什么?提示:它可能说转换不明确。我也会告诉我们在实际的开发过程中使用static_cast。我希望看到这段代码的学生会记住user4581301的建议。但是,如果你仍然不知道static_cast,你可以跳过他的建议。这段代码只适用于初学者。对Pete Becker说:这不是由于转换模糊而导致的错误。感谢你的关注。使用“std:”在所有对象上都可以增加代码的长度,使其可读性降低。我认为省略“std”对可读性有好处,这是标准库的名称空间,即使省略了其他名称空间。我是否应该在stackoverflow.com上为您找到一些问题,其中有人被一个完全不可理解的编译错误完全弄糊涂了,其唯一原因是使用名称空间std;
?我多年来一直在回答这些问题……欢迎您访问在不事先知道的情况下,做一次心理练习,试图找出导致编译错误的原因。你不必再为我找到这些问题。我认为每次对类似错误的回答都会让你感到疲惫。我认为你是一个好人,对犯下这样的错误感到抱歉,并努力不让它发生。你的努力肯定会有助于世界的发展。然而,即使初学者很容易犯错误,提高代码的可读性也是非常重要的。即使你的问题被一些初学者对名称空间的不成熟使用所淹没,不利用C++语法似乎不是一个聪明的主意。相反,这是一个好主意向他们解释如何正确使用名称空间的更好方法。
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);
#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;
}