ページ 11

1つの演算子に対して複数のオーバーロードはできない?

Posted: 2011年8月04日(木) 23:34
by MoNoQLoREATOR
例えば、次のコードをコンパイルすると、VisualStudioではエラーが出て失敗してしまいます。

コード:

template <typename SLIST>
class slist{
	public:
	std::list<SLIST> myList;
	void slist::operator+= (std::list &list){
		myList.merge(list);
	}

	void slist::operator+= (SLIST &ele){
		myList.push_back(ele);
	}
};
C++にはオーバーロードというルールがあって、「引数の型や数が違えば同じ名前の関数を定義してもよい」はずですよね。もっとも、operator+=を関数と呼べるかどうかわかりませんし、そもそもoperator自体がオーバーロードですからね。

ご教授よろしくお願い致します。

Re: 1つの演算子に対して複数のオーバーロードはできない?

Posted: 2011年8月05日(金) 00:36
by 晩御飯
オーバーロードよりも気にすべき点があると思うのです。

コード:

template <typename SLIST>
class slist{
    std::list<SLIST> myList;
public:
    void operator+= (std::list &list){
        myList.merge(list);
    }
 
    void operator+= (SLIST &ele){
        myList.push_back(ele);
    }
};

Re: 1つの演算子に対して複数のオーバーロードはできない?

Posted: 2011年8月05日(金) 02:11
by GRAM
たとえば一つ目のオーバーロードの引数でstd::listのテンプレートパラメータが不足しています。
少なくとも自分の環境では

error C2955: 'std::list' : クラス テンプレート を使用するには テンプレート 引数リストが必要です
1> 'std::list' の宣言を確認してください。
1> コンパイルされたクラスの テンプレート のインスタンス化 'slist<SLIST>' の参照を確認してください
1> with
1> [
1> SLIST=int
1> ]

と出るのですが・・・。
オーバーロード自体は何の問題もなくできるはずですよ。
実装がC++のコンベンションに従っているかと聞かれれば話は全く別ですが。
晩御飯さんはこの辺のことを言ってるのだと思いますが、たとえば
slist<int> sl;
s += 1;とかはこのコードではできないですね。オーバーロードとは別の理由で・・・


以下のコードは何の問題もなくコンパイルに成功します

コード:

[#include<iostream>
#include <list>
using namespace std;

template <typename SLIST>
class slist{
    std::list<SLIST> myList;
public:
    void operator+= (std::list<SLIST> &list){
        myList.merge(list);
    }
 
    void operator+= (SLIST &ele){
        myList.push_back(ele);
    }
}; 

int main(){
	slist<int> s;
	list<int> l;
	l.push_back(1);

	s += l;
	int a = 1;
	s += a;
}

Re: 1つの演算子に対して複数のオーバーロードはできない?

Posted: 2011年8月05日(金) 09:07
by MoNoQLoREATOR
解決しました。ありがとうございました。
slist::operator
でコンパイルが通っちゃったから無意識に<SLIST>を省略してしまったようです。
しかし、
std::list &list
と書いたらコンパイルエラーが出そうなものですが、なぜ出なかったのでしょうか?そういう風に書くこともあるのですか?