C++のテンプレートに関する質問です。

下記のソースをcygwinのgcc(v4.3.4)でコンパイルするとエラーとなります。

エラー内容
$ gcc -o test temp5.cpp -lstdc++
temp5.cpp: In function ‘int main()’:
temp5.cpp:12: error: call of overloaded ‘max(int, int)’ is ambiguous
temp5.cpp:6: note: candidates are: X max(X, X) [with X = int]
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algobase.h:210: note:
const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]


何が間違っているのか、教えてください。
VC++6.0ではコンパイル可能です。
宜しくお願いします。

以下ソース
---------------------------------
#include <iostream>
using namespace std;

template <typename X>

X max(X var1 , X var2) {
if (var1 > var2) return var1;
else return var2;
}

int main() {
cout << max(10 , 100);
return 0;
}

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/04/15 16:40:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:tdoi No.1

回答回数174ベストアンサー獲得回数75

ポイント35pt

エラーメッセージそのものなのですが、STLの中(stl_algobase.h)に以下の定義があります。

namespace std {
  template<typename _Tp>
  inline const _Tp&
  max(const _Tp& __a, const _Tp& __b)
  {
    // concept requirements
    __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
    //return  __a < __b ? __b : __a;
    if (__a < __b)
      return __b;
    return __a;
  }
}

mizore_chanさんのコード中にも次のような定義があります。

template <typename X>
X max(X var1 , X var2) {
if (var1 > var2) return var1;
else return var2;
}

前者の方は、std名前空間中のmaxという関数、後者はグローバルスコープ中のmaxという関数で実態は異なりますので、定義自体は問題ありません。きっちり名前空間を書けば、

std::max
::max

という別の名前になります。

ところが、コードの先頭で、

using namespace std;

と記述しているため、std名前空間は省略可能になります。

すると、

max(10 , 100);

という呼び出しが、


std::max(10 , 100);

なのか

::max(10 , 100);

なのかが判別つかないという意味のエラーです。

確認していませんが、対処方としては、上記のように名前空間を明示してあげればよいかと思います。

なお、VC6で問題なく動作するということに関しては、ある種のVC6のバグのようなもので、windows.hで定義されているマクロにより、std::maxやstd::minが使えません。そのため、曖昧さが発生せずに問題なく動作します。

なお、こちらの解決策は、次のサイトなどで紹介されているように、NOMINMAXをdefineしてあげれば解決します。

http://d.hatena.ne.jp/pyopyopyo/20100329/p1

恐らくですが、stdafx.hなどをincludeする前に、NOMINMAXをdefineするとVC6でも同じエラーが出ると思います。

何かの参考になれば。

id:mizore_chan

ありがとう御座います。

名前空間なのですね。

Cでいったら、includeしたライブラリに同じ名前の関数があった、というようなことでしょうか。

ともかく、上記内容を確認してみます。

2011/04/08 17:23:58
id:taroe No.2

回答回数1099ベストアンサー獲得回数132

id:mizore_chan

ありがとう御座います。

名前空間を調べました。

2011/04/13 06:22:28

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません