不明确的运算符 <<

发布于 2024-09-11 15:15:37 字数 1436 浏览 3 评论 0 原文

#include "stdafx.h"
#include "Record.h"

template<class T>//If I make instead of template regular fnc this compiles  
//otherwise I'm getting an error (listed on the very bottom) saying  
// that operator << is ambiguous, WHY?
ostream& operator<<(ostream& out, const T& obj)
{
    out << "Price: " 
        << (obj.getPrice()) << '\t'//this line causes this error
        << "Count: "
        << obj.getCount()
        << '\n';
    return out;
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<Record> v;
    v.reserve(10);
    for (int i = 0; i < 10; ++i)
    {
        v.push_back(Record(rand()%(10 - 0)));
    }
    copy(v.begin(),v.end(),ostream_iterator<Record>(cout, "\n"));
    return 0;
}

//Record class
class Record
{
    private:
        int myPrice_;
        int myCount_;
        static int TOTAL_;
    public:
        Record(){}
        Record(int price):myPrice_(price),myCount_(++TOTAL_)
        {/*Empty*/}
        int getPrice()const
        {
            return myPrice_;
        }

        int getCount()const
        {
            return myCount_;
        }
        bool operator<(const Record& right)
        {
            return (myPrice_ < right.myPrice_) && (myCount_ < right.myCount_);
        }
};

int Record::TOTAL_ = 0;

错误 2 错误 C2593:“运算符 <<”不明确

#include "stdafx.h"
#include "Record.h"

template<class T>//If I make instead of template regular fnc this compiles  
//otherwise I'm getting an error (listed on the very bottom) saying  
// that operator << is ambiguous, WHY?
ostream& operator<<(ostream& out, const T& obj)
{
    out << "Price: " 
        << (obj.getPrice()) << '\t'//this line causes this error
        << "Count: "
        << obj.getCount()
        << '\n';
    return out;
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<Record> v;
    v.reserve(10);
    for (int i = 0; i < 10; ++i)
    {
        v.push_back(Record(rand()%(10 - 0)));
    }
    copy(v.begin(),v.end(),ostream_iterator<Record>(cout, "\n"));
    return 0;
}

//Record class
class Record
{
    private:
        int myPrice_;
        int myCount_;
        static int TOTAL_;
    public:
        Record(){}
        Record(int price):myPrice_(price),myCount_(++TOTAL_)
        {/*Empty*/}
        int getPrice()const
        {
            return myPrice_;
        }

        int getCount()const
        {
            return myCount_;
        }
        bool operator<(const Record& right)
        {
            return (myPrice_ < right.myPrice_) && (myCount_ < right.myCount_);
        }
};

int Record::TOTAL_ = 0;

Error 2 error C2593: 'operator <<' is ambiguous

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

海拔太高太耀眼 2024-09-18 15:15:37

operator<<( ostream &, ... ) 背后的概念是每个类都可以有自己的重载,以有意义的方式处理特定的类。

这意味着您将获得处理 Record 对象的操作符 <<( ostream &, const Record & ) 和操作符<<( ostream &, const std::string & )。 ) 处理标准字符串,operator<<( ostream &, const FooClass & ) 处理 FooClass 对象。这些函数中的每一个都知道如何处理它所声明的对象类型,因为它们中的每一个都需要不同的处理。 (例如 getPrice() / getCount() 用于 Record,或 getFoo() / getBar( ) for FooClass。)

你的模板粗暴地践踏了整个概念。通过将其定义为模板函数(将匹配任何类),您不仅会与标准/您的标准中已有的operator<<()的许多定义发生冲突代码库,但所有可能重载。

编译器如何决定是否使用运算符<<( ostream &, const std::string & ) 还是您的模板?它不能,所以它绝望地举起双手并放弃。这就是错误告诉你的。

The concept behind operator<<( ostream &, ... ) is that every class can have its own overload, handling that specific class in a way that make sense.

That means you get operator<<( ostream &, const Record & ) which handles Record objects, and operator<<( ostream &, const std::string & ) which handles standard strings, and operator<<( ostream &, const FooClass & ) which handles FooClass objects. Each of these functions knows how to handle the object type it has been declared for, because each of them requires a different handling. (E.g. getPrice() / getCount() for Record, or getFoo() / getBar() for FooClass.)

Your template is trampling roughshod over the whole concept. By defining it as a template function (which would match any class), you not only collide with the many definitions of operator<<() already in the standard / your codebase, but all possible overloadings.

How could the compiler decide whether to use operator<<( ostream &, const std::string & ) or your template? It cannot, so it throws up its hands in despair and gives up. That's what the error is telling you.

山川志 2024-09-18 15:15:37

首先,您需要更仔细地阅读错误消息。作为替代方案,请考虑将语句分解,如下所示:

out << "Price: ";
out << (obj.getPrice());
out << "\tCount: ";
out << obj.getCount();
out << '\n';

当您这样做时,您会意识到真正导致问题的原因不是您尝试打印出 getPrice()< /code>,但是您尝试打印出“价格:”

出现问题的原因是编译器不知道是使用普通重载来打印字符串,还是使用定义的模板来打印字符串。后者会导致无限递归,并且它实际上无法编译,因为它需要一个可以调用 getPricegetCount 的对象来正确编译 - 但它有一个匹配的签名,所以编译器说它不明确,这就是结束。

First, you need to read the error message more carefully. As an alternative, consider breaking the statement up, something like this:

out << "Price: ";
out << (obj.getPrice());
out << "\tCount: ";
out << obj.getCount();
out << '\n';

When you do, you'll realize that what's really causing the problem is not where you try to print out getPrice(), but where you try to print out "Price: ".

The problem is arising because the compiler doesn't know whether to use the normal overload to print out the string, or to use the template being defined to print it out. The latter would cause infinite recursion, and it couldn't actually compile since it requires an object on which you can/could call getPrice and getCount to compile correctly -- but it has a signature that matches, so the compiler says it's ambiguous, and that's the end of that.

呆橘 2024-09-18 15:15:37

错误的原因是您的模板化重载与另一个模板化重载冲突,并且没有理由优先选择一个模板而不是另一个模板:(

template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);

template <class T>
basic_ostream<char, char_traits<char> >& operator<< (basic_ostream<char, char_traits<char> >&, const T&);

//which one is preferable when you ask for: cout << "literal";?

ostream 应该是 basic_ostream >。)

将重载作为模板的整个想法是有问题的,因为重载显然无法处理除 Record 之外的任何其他类。

可能有一些技术允许您通过一些模板元编程(enable_if 和 Traits)为许多不相关的类似 Record 的类提供单个模板化重载,如果这是想法的话。

The reason of the error is that your templated overload is conflicting with another templated overload, and there is no reason to prefer one template to another:

template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);

template <class T>
basic_ostream<char, char_traits<char> >& operator<< (basic_ostream<char, char_traits<char> >&, const T&);

//which one is preferable when you ask for: cout << "literal";?

(ostream should be a typedef for basic_ostream<char, char_traits<char> >.)

The whole idea of making your overload a template is questionable, seeing that the overload clearly cannot handle any other class than your Record.

There probably are techniques to allow you to provide a single templated overload for a number of unrelated Record-like classes with a little template metaprogramming (enable_if and traits), if that is the idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文