• ベストアンサー

プログラミング言語C++のエラー

#include <iostream> #include <string> using namespace std; template <typename T> T max(T n1, T n2) { if(n1 > n2) { return n1; } return n2; } int main(){ cout << max<int>(1,2) << endl; cout << max<double>(1.75,3.12) << endl; string s1 = "aiu",s2 = "eo"; cout << max<string>(s1,s2) << endl; return 0; } このコードを入力すると、添付写真のようなエラーが出ます。使用しているのはmacOSのVisual Studio codeです。明らかにいじってはいけない場所のファイル /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/include/c++/v1/__algorithm/max.h (添付写真のエラー表示下部のパス)が勝手に参照され、引数が一致してしまっているオーバーロードした関数となってしまいます。maxをMaxなどとすると問題は解決するのですが、既存のコードを編集する際、いちいちmaxでエラーが出ると不便です。 ちなみにテンプレートではなく、引数ごとに関数を作ればエラーは出ません。 解決方法を知っている方が居れば教えてほしいです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

へぇ・・・面白いなぁ。 最初に言っておくと、僕はC++の専門でも何でもない。 ただ、原因としては「名前空間の衝突だろうな」って事はアタリは付いた。 つまり、「std」と言うライブラリ内に既にmax、minってのが定義されてんだよ。 だから「貴方独自のmax、minを定義した」時点で、「既にstd内にmax、minがあります」ってぇんで、「名前の衝突が起きてる」のがエラーの原因なわけ。 んで、 > 解決方法を知っている方が居れば教えてほしいです。 要は名前空間をワケちまえばいいんだ。 言語仕様上は良く分からんのだが、一番簡単に思いつくのは、using namespace std;; の一行を削除することだな。 でもこれを削除すると、例えばcoutはstd::cout、endlはstd::endlと、「どこに所属したブツか」ってのを明確に書かなアカンくなる。 それよりも問題は、コンパイラに依ると思うんだけど、using namespace std;;を削除してなお、「maxは使えません」なんかの類のエラーが続けて出る場合もあり得るんだ。 少なくとも、clangみたいなコンパイラだとそうだ。従って、using namespace std;;を削除するのはあまり効果がない・・・・・・と言うか、言語仕様上どうなってるのか分からんのだけど、少なくともclangみたいなコンパイラだとそうなってる。 んで、もう一つの解決策、って言うのは「自分が定義したmax」と言うテンプレート関数を、「別名前空間内定義」として分けちゃう事だ。 例えば次のように書く。 #include <iostream> #include <string> using namespace std; namespace foo{ template <typename T> T max(T n1, T n2) { if (n1 > n2) { return n1; } return n2; } } int main(void) { cout << foo::max<int>(1, 2) << endl; cout << foo::max<double>(1.75, 3.12) << endl; string s1 = "aiu", s2 = "eo"; cout << foo::max<std::string>(s1, s2) << endl; return 0; } 例えばここでは、fooと言う名前空間を定義して、「その中で」テンプレート関数maxを定義する。そうすれが、このmaxはstdに含まれるmaxとは「違うモノなんだ」とコンパイラに教える事が出来る。 使う際にはfoo::maxになるんだけど(つまり、foo名前空間内のmaxを指定する)、これでstd::maxとは別物、と認識されるので名前の衝突は回避される筈だ。

asitanoyozora
質問者

お礼

回答ありがとうございます!たしかにusing namespace std;を消しても同じエラーが出てきました。あるサイトで勉強するためのものだったのですが、そのサイトは何かとミスが多かったのでこれも一部だと思います... そして別の名前空間を作るといった解決方法を提案してくださり、ありがとうございます!実行した結果、理想の結果になりました! 新たな発見があったので、これからの参考にもさせていただきます!

その他の回答 (1)

回答No.1

std::maxが定義されているために、どちらのテンプレートを使用すればよいのかが判断できずにエラーになっているのでしょう。 std::maxに任せてしまって問題ないのであれば、関数テンプレートの定義を削除してしまえばいいように思います。

asitanoyozora
質問者

お礼

回答ありがとうございます! サイトを見て勉強していたのですが、このサイトも何かとミスが多かったのでこれもその一種ですかね?とにかく今後は元々あった処理に任せようと思います!

関連するQ&A