簡體   English   中英

二進制運算符在模板類上重載

[英]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.

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