![](/img/trans.png)
[英]Template instantiation unable to match argument list for overloaded stream operator when invoked between headers
[英]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.