[英]Binary operator overloading on a templated class
我最近試圖測量我的運算符重載/模板能力,並作為一個小測試,創建下面的Container類。 雖然此代碼編譯良好並且在MSVC 2008(顯示11)下正常工作,但MinGW / GCC和Comeau都在operator+
過載時阻塞。 因為我比MSVC更信任他們,所以我想弄清楚我做錯了什么。
這是代碼:
#include <iostream>
using namespace std;
template <typename T>
class Container
{
friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
public: void setobj(T ob);
T getobj();
private: T obj;
};
template <typename T>
void Container<T>::setobj(T ob)
{
obj = ob;
}
template <typename T>
T Container<T>::getobj()
{
return obj;
}
template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
{
Container<T> temp;
temp.obj = lhs.obj + rhs.obj;
return temp;
}
int main()
{
Container<int> a, b;
a.setobj(5);
b.setobj(6);
Container<int> c = a + b;
cout << c.getobj() << endl;
return 0;
}
這是Comeau給出的錯誤:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 27: error: an explicit template argument list is not allowed
on this declaration
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
^
1 error detected in the compilation of "ComeauTest.c".
我很難讓Comeau / MingGW去打球,所以我轉向你們。 很長一段時間以來,我的大腦在C ++語法的重壓下融化了這么多,所以我覺得有點尷尬;)。
編輯 :消除了初始Comeau轉儲中列出的(不相關的)左值錯誤。
由於這個論壇發帖,我找到了解決方案。 基本上,你需要有一個函數原型才能在類中使用'friend',但是你還需要聲明這個類才能正確定義函數原型。 因此,解決方案是在頂部有兩個原型定義(功能和類)。 以下代碼在所有三個編譯器下編譯:
#include <iostream>
using namespace std;
//added lines below
template<typename T> class Container;
template<typename T> Container<T> operator+ (Container<T>& lhs, Container<T>& rhs);
template <typename T>
class Container
{
friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
public: void setobj(T ob);
T getobj();
private: T obj;
};
template <typename T>
void Container<T>::setobj(T ob)
{
obj = ob;
}
template <typename T>
T Container<T>::getobj()
{
return obj;
}
template <typename T>
Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
{
Container<T> temp;
temp.obj = lhs.obj + rhs.obj;
return temp;
}
int main()
{
Container<int> a, b;
a.setobj(5);
b.setobj(6);
Container<int> c = a + b;
cout << c.getobj() << endl;
return 0;
}
template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
operator+
之后的“<>”應該被刪除,因為您只是聲明一個新模板,而不是專門的一般模板。 此外,至少g++
想要在友元聲明之前看到模板聲明,因此需要在聲明Container
之前移動它。 所以聲明的以下順序有效:
// forward declaration of Container<T>
template <typename T>
class Container;
template <typename T>
Container<T> operator+(Container<T>& lhs, Container<T>& rhs)
{ ... }
template <typename T>
class Container
{
friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
...
};
我在GCC下給了它一個鏡頭並讓它編譯並運行一些更改。 為了讓GCC滿意,我必須做出兩個改變。
一個是朋友模板功能的聲明。 它是自己的模板聲明,與第一類分開,因此我使用U而不是Container類'T. 我也在運算符+之后擺脫了<>。 除非你正在編寫模板專業化,否則我認為你不需要這些。
template<typename U>
friend Container<U> operator+ (Container<U>& lhs, Container<U>& rhs);
二,行
Container<int>& c = a + b;
沒有與GCC一起飛行,因為你要求存儲對臨時的引用(添加的結果)。 我刪除了&符號,以便有一個存儲結果的地方。
我剛看到你的帖子,因為前向聲明也有效。 我想我會發布這個作為不需要它們的替代方案。 當然我只在GCC測試過......
你最好直接在類中定義函數。 此外,您應該將參數作為const
引用傳遞。
template <typename T>
class Container
{
public:
friend Container operator+ (Container const & lhs, Container const & rhs)
{
// ...
}
};
'operator +'不是成員函數,它不是模板化的。 它只是運算符+,它采用模板化參數。
template <typename T>
Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.