C++ 操作员的全局过载

C++ 操作员的全局过载,c++,operator-overloading,C++,Operator Overloading,我已经学习了操作符注意stackoverflow的类型是const char[],而不是std::string。这意味着不会调用您的重载,但会调用标准库中的重载,因为它是完全匹配的,并且不需要从const char[]到std::string的隐式转换 顺便说一句:可以找到它,因为。请注意,stackoverflow的类型是const char[],而不是std::string。这意味着不会调用您的重载,但会调用标准库中的重载,因为它是完全匹配的,并且不需要从const char[]到std::

我已经学习了操作符注意stackoverflow的类型是const char[],而不是std::string。这意味着不会调用您的重载,但会调用标准库中的重载,因为它是完全匹配的,并且不需要从const char[]到std::string的隐式转换

顺便说一句:可以找到它,因为。

请注意,stackoverflow的类型是const char[],而不是std::string。这意味着不会调用您的重载,但会调用标准库中的重载,因为它是完全匹配的,并且不需要从const char[]到std::string的隐式转换


顺便说一句:可以找到它,因为。

您可以全局重载,但stackoverflow不是std::字符串,因此不使用您的字符串。 在标准库中已经存在这样的过载

为了确保它能正常工作,请将第一个重载移出类定义并使其成为非友元。 必须声明为friend的唯一原因是您已经在类定义中声明了它,否则它将是成员函数

这将按照您的预期工作:

struct Test
{
    std::string d_data;
    Test(const std::string & data) : d_data{data} {}
};

std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
    ostr << obj.d_data << '\n';
    return ostr;
}

int main()
{
    Test t1("one");
    std::cout << t1;
    Test t2("two");
    std::cout << t2;
}

您可以全局重载,但stackoverflow不是std::字符串,因此不使用您的字符串。 在标准库中已经存在这样的过载

为了确保它能正常工作,请将第一个重载移出类定义并使其成为非友元。 必须声明为friend的唯一原因是您已经在类定义中声明了它,否则它将是成员函数

这将按照您的预期工作:

struct Test
{
    std::string d_data;
    Test(const std::string & data) : d_data{data} {}
};

std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
    ostr << obj.d_data << '\n';
    return ostr;
}

int main()
{
    Test t1("one");
    std::cout << t1;
    Test t2("two");
    std::cout << t2;
}
您的操作员使用

std::cout << "stackoverflow";
所以调用这个操作符而不是你的操作符

此外,在您的运营商内部

std::ostream & operator<<(std::ostream & os, const std::string & s)
{
    os << s << '\n';
    return os;
}
您的操作员使用

std::cout << "stackoverflow";
所以调用这个操作符而不是你的操作符

此外,在您的运营商内部

std::ostream & operator<<(std::ostream & os, const std::string & s)
{
    os << s << '\n';
    return os;
}

您声称有效的第一个示例不应该像您所展示的那样有效。重载操作不允许你这样做。运算符中的所有类型都不是您自己的,因此该运算符不是您自己定义的。您声称有效的第一个示例完全不应该像您所展示的那样有效。重载操作不允许你这样做。运算符中的所有类型都不是您的,因此该运算符不是您定义的。@我意识到它与OP的情况不太匹配。std名称空间的修改是UB,但OP实际上并没有修改它。而且,在自定义类型上提供重载应该很好。@U标记我意识到它与OP的情况不太匹配。std名称空间的修改是UB,但OP实际上并没有修改它。而且,在自定义类型上提供重载也可以。
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
std::ostream & operator<<(std::ostream & os, const std::string & s)
{
    os << s << '\n';
    return os;
}
#include <iostream>
#include <string>

std::ostream & operator<<(std::ostream & os, const char *s)
{
    return std::operator <<( os, s ) << '\n';
}

int main()
{
    std::cout << "stackoverflow";
    std::cout << "stackoverflow";
}
stackoverflow
stackoverflow