簡體   English   中英

為什么實例化流操作符模板而不是全局重載操作符?

[英]Why instantiation of template of stream operator occurs instead of global overloaded operator?

假設以下代碼。 有一個類MyStream女巫有模板重載operator <<。 全局重載運算符MyStream&operator <<(MyStream&,const MyClass&)。 令人困惑的是(通過編譯器)為兩個幾乎相同的情況生成不同的方法(參見main()函數的主體)。 我認為應該在兩種情況下使用全局運算符,但事實並非如此。 為什么這樣?

#include <iostream>

class MyStream;
class MyClass;
MyStream& operator << (MyStream& stream, const MyClass&);

class MyStream
{
public:
    template <typename T>
    MyStream& operator << (const T&)
    {
        std::cout << __FUNCTION__ << " " << typeid(T).name() << std::endl;
        return *this;
    }
};

class MyClass
{
};

MyStream& operator << (MyStream& stream, const MyClass&)
{
    std::cout << __FUNCTION__ << " " << typeid(MyClass).name() << std::endl;
    return stream;
}

int main(int, char**)
{
    // 1. Used globally defined operator for MyClass
    MyStream() << int() << MyClass();
    std::cout << std::endl;

    // 2. Template instantiation
    MyStream() << MyClass();

    std::cin.get();
    return 0;
}

使用Microsift Visual C ++編譯器9.0(x86)編譯的程序輸出:

MyStream::operator << int
operator << class MyClass

MyStream::operator << class MyClass
// 2. Template instantiation
 MyStream() << MyClass();

在這種情況下,表達式MyStream()創建一個臨時對象(一個rvalue ),它不能綁定到非const引用,因此編譯器選擇成員函數模板,因為為了調用free函數,臨時對象必須是作為函數的第一個參數傳遞,這在這里是不可能的,因為自由函數的第一個參數的類型是非const引用。 所以MyStream << MyClass()調用成員函數。

但是當你寫這個:

// 1. Used globally defined operator for MyClass
MyStream() << int() << MyClass();

它首先調用傳遞int()的成員函數,並且成員函數返回一個MyStream&類型的對象,現在它可以作為第一個參數傳遞給自由函數(因為它不再是一個rvalue ,現在它是一個左值 ),然后它調用free函數,傳遞MyStream&類型的對象作為第一個參數,將MyClass()作為第二個參數傳遞。

這很有趣,類似的事情發生在這里:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM