C++でのオーバーロードのバグ回避方法を知りたい

このQ&Aのポイント
  • C++でプログラムの途中で発生するオーバーロード関数のエラーについて調査しました。
  • Visual C++のバージョン5.0で発生するバグであることが判明しましたが、回避方法は分かりません。
  • 関係する部分のコードを抜粋しましたが、どのように対処すべきかわかりません。他のC++開発者はどのように対応しているのか教えてください。
回答を見る
  • ベストアンサー

C++でオーバーロードに関するバグの回避

プログラムの途中で次のエラーが出ました。 error C2667: '>>' : 2個のオーバーロード関数があいまいで最適な変換ができません。 error C2593: 'operator >>' があいまいです。 調べましたらVisual C++自体のバグらしいのです。 http://support.microsoft.com/support/kb/articles/Q240/8/69.ASP http://support.microsoft.com/support/kb/articles/Q128/3/44.ASP 僕のVisual C++はVersion 5.0です。 学校のはVersion 6.0ですのでこのバグは出ません。 このバグを回避する方法は無いのでしょうか? Version 5.0を使用されている方は結構いらっしゃるのではないかと 思うのですが、皆さんはどうされているのでしょうか? 一応、関係ありそうなところだけ抜粋しました。 ■main.cpp shareholder total[size]; // 全員の名前が入る予定のtotal[]を // class "shareholder"で定義 total[s].getData(input); // 関数getData()を呼ぶ // inputはifstreamで定義されている ■shareholder.h class shareholder { public: shareholder(); virtual ~shareholder(); void getData(ifstream&); private: string firstName; string lastName; }; ■shareholder.cpp void shareholder::getData(ifstream& inputFunction) { inputFunction >> firstName >> lastName; // ここでエラーが発生 }

  • sucker
  • お礼率91% (213/234)

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

  • ベストアンサー
  • Fooky
  • ベストアンサー率71% (59/82)
回答No.2

> 回避方法って、要するに>>を使わなきゃいいんですよ。 その通り。 …で終るのも殺生なんで、代替案を。 1.getline(inputFunction, firstName)   でfirstNameに一行読み込み、   lastName = firstName.substr(firstName.rfind(' ') + 1)   firstName = firstName.substr(0, firstName.find(' '))   とかやって分ける。     でもなぁ。これもおなじバグが影響しそう。   特に、Q240/8/69.ASP のバグがほんとに影響してるなら、   多分、出ますね。   std/bastring.hの中で、operator>>(ifstream, string)と同じ   ように、バリバリtemplateを使って宣言されてるんで。 2.char str[MAX_BYTES_PER_LINE+1];   inputFunction.getline(str, MAX_BYTES_PER_LINE);   でstrに一行読み込み、   char fn[MAX_BYTES_PER_LINE+1], ln[MAX_BYTES_PER_LINE+1];   sscanf(str, "%s %s", fn, ln);   で分ける。分け方は、strで初期化したstringオブジェクトをつくって、   1.と同様の方法で分けても良いです。Cの関数を使いたくないなら。 3.最初からストリームをCの標準入出力関数fopen(...)で開いて、   fscanfで読み込む。   *scanf(...)は、ifstream::operator>>(...)と同じくスペースを区切り記号   とみなすので、getline(...)のように分ける手間は省けます。 他にも色々あると思います。とにかく、やばいのは使わないことです。 私の周りにも、VC++経験者で(ちなみに私はGNU C++です) templateを極端に嫌う人がいます。(ちなみに私はこれでもかって位 使います。)

sucker
質問者

お礼

>>を使わない、というのはそういう意味だったのですね。 1.getline(inputFunction, firstName)が見事成功しました。 firstNameの名前をfullNameに変えてクラスのメンバーに入れましたが その他はFookyさんの回答をコピーしただけです。 2.と3.はまだ試してません。今度やってみます (というか、もう動いたのでいいのですが)。 オーバーロードというのが何なのかさえ判らないというのもあるのですが、 あいまいです、ってぶっきらぼうに言われても困りますよね。 だからバグなんでしょうけど。 そういうエラーメッセージの方がよっぽどあいまいだと思うのですが。 とにかく、この問題が発生する度に毎回これを使えばいいのですね。 本当に助かりました。ありがとうございました。

その他の回答 (1)

  • KOH_da
  • ベストアンサー率31% (161/506)
回答No.1

回避方法って、要するに>>を使わなきゃいいんですよ。

sucker
質問者

補足

確かに的を得た回答でしたが、Fookyさんのように詳しく書いて戴きたかったです。そもそも「>>を使わなきゃいい」と聞いて「ああ、なるほど」というレベルであれば質問はしていないと思います。仕事としてではなく、自発的に回答して下さっているのですから、1から10まですべて教えて欲しいとは言いませんが、もう少し説明して下さっても罰は当たらないと思います。その分、質問者は回答者に感謝の言葉を返しているのです。今回は残念ですがKOH_daさんに対して感謝の言葉を述べることはできません。しかし、理由は理解していただけると思っています。次回からはよろしくお願いします。

関連するQ&A

  • C2146を回避するにはどうしたら良いのでしょうか

    いつもここにお世話になってますm(__)m。今回は下記の様なエラーが出てしまい、困っております(--;)。 <エラー内容> 1>C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\winnt.h(222) : error C2146: 構文エラー : ';' が、識別子 'PVOID64' の前に必要です。 1>C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\winnt.h(222) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません エラーが起こっているのはwinnt.h内の「typedef void * POINTER_64 PVOID64;」という部分なのですが(他にもありますが)、winnt.hは弄ってないのです。 ネットで検索したところインクルードファイルディレクトリの指定の順番が怪しそうなので、「ツール」「オプション」でPlatformSDK関連が一番上に来るように変更(実行可能ファイル、インクルードファイル、ライブラリファイル)してリビルドしてみましたが結果は変わりませんでした。 他にチェックすべき点をお教え頂けると助かります。 [環境] ・WindowsXP(SP2) ・Visual Studio 2005 Professional(C++、SPなし)

  • フレンド関数を利用したオーバーロードでコンパイルエラー

    独習C++(第3版)で学習していますが、書籍通りに入力してもコンパイルエラーが出てしまい、困っております。 P.199 6.5.フレンド演算子関数の使用にあるソースコードをそのままコピーしただけです。 フレンド関数を利用し、演算子オーバーロードをすると、コンパイルエラーが発生してしまうようです。 (10): friend coord operator+(coord ob1,int i); C:\jsp\tools\samp13\XXXX.cpp(10) : fatal error C1001: 内部コンパイラ エラー (コンパイラ ファイル 'msc1.cpp', 行番号 1786) Visual C++ のサポート情報 コマンドを選択してください ヘルプ メニュー、 またはサポート情報のヘルプ ファイルを参照してください 少し検索したところVC++6.0だとバグで起こってしまうとのことですが、この状態からコンパイルエラーを無くすには何をしたらよいのでしょうか?

  • C++でのエラーメッセージの意味

    C:\Program Files\Microsoft Visual Studio\MyProjects\hello\hello.cpp(73) : error C2562: 'main' : 関数は 'void' 型として宣言されていますが、値を返しました。 C:\Program Files\Microsoft Visual Studio\MyProjects\hello\hello.cpp(6) : 'main' の宣言を確認してください。 cl.exe の実行エラー hello.exe - エラー 1、警告 0 ************************** C++で、コンパイルしたら、上記のエラーメッセージが表示されました。 考えられるエラーは何でしょうか? どのように直したらよいでしょうか? どうかお教えください。

  • Visual C++ 2008で .cファイルのコンパイラができない

    現在Microsoft Visual C++ 2008 Express Editionでc言語を勉強していて 今の所しばらくc++の勉強をする予定はありませんので、 c言語のみ勉強したいのですがVisual C++ 2008で、.cファイルを作成し、 これをコンパイルしようとすると必ずエラーが出ます。 原因を色々なページを回って探したのですが 「.cppファイルにすればコンパイルできます」という回答しか見当たりません c言語でも最初のうちは.cppファイルでも問題なく動くようですが、 高度なレベルに行くとcpp独自のエラーが出ると聞いております。 このような状態でc言語を勉強するのも微妙です なんとか.cファイルでコンパイラする方法は無いでしょうか? あるいはVisual C++ 2008に代わるお勧めのソフトでも結構です よろしくお願いします。

  • xml 大量に作成したい

    for文を使用してxmlファイルを一気に作成したいと思っています。 下記の様にコーディングしたのですがエラー(型のオペランドを使用することはできません)が 表示され作成できません。 var xml= new XDocument(); for (int a = 1; a == 10000;a++) { xml = xml + new XDocument(        new XDeclaration( "1.0" , "utf-8" , "true" ) ,        new XComment( "LINQ to XML Sample http://keicode.com/" ) ,         new XElement( "Employees", new XElement( "Employee", new XElement("FirstName", "Keisuke"), new XElement("LastName", "Oyama"), new XElement("ID", a) ) ) ); } xml.Save( @"C:\Temp\Sample.xml" ); 結果として <?xml version="1.0" encoding="utf-8"?> <!--LINQ to XML Sample http://keicode.com/--> <Employees> <Employee> <FirstName>Keisuke</FirstName> <LastName>Oyama</LastName> <ID>1</ID> </Employee> </Employees> ~~~~10000万個~~~ <Employees> <Employee> <FirstName>Keisuke</FirstName> <LastName>Oyama</LastName> <ID>10000</ID> </Employee> </Employees> の様なファイルが作成したいのです。

    • 締切済み
    • XML
  • ifstreamについて

    ifstream でファイルを読み込もうとしているのですが、上手くいきません。 ソース A.cpp #include"A.h" void Broker::read_file(ifstream in) { in >> shikin; } int main(void) { ifstream in; in.open("hoge.txt"); Broker b; b.read_file(in); b.show(); } A.h #include<fstream.h> #include<iostream.h> class Broker{ int shikin; int nensu; double nenri; int tesuryo; public: Broker() { shikin = 0; nensu = 0; nenri = 0.0; tesuryo = 0; } void read_file(ifstream in); void show() {cout << shikin << endl;} }; 以上のようなプログラムなのですが、 コンパイルすると エラー E2247 'ios::basic_ios(const ios &)' はアクセスできない(関数 ifstream::basic_ifstream(ifstream &) ) エラー E2125  コンパイラは 'copy constructor' クラスの istream を作成できない(関数 ifstream::basic_ifstream(ifstream &) ) とのエラーが出てきて実行できません。 コンパイラ C++Builder OS XP なにが原因なのかが分かりません。 本当に初心者な質問ですが、よろしくお願いします。 (何か足りない情報などがありましたら、お手数ですがその掲示板にお願いします)

  • Visual C++ 2005 MFCアプリのクラス作成について

    Windows XP SP3 Visual C++ 2005 pro MFCアプリケーション シングルドキュメント 以上の環境でアプリケーションを作りたいと思っています。 C++は、C言語をベースという意味ではそれなりにはわかっているつもりです(自信はないですが...)。 本当はSDKを学んだ方がよろしいんでしょうが、時間の都合上MFCでやることにしました。 ちなみに、VC++を使ったプログラミングは初めてのものです。 そこで質問なのですが、 通常のC++においてクラスを作るときは、cppファイルとhファイルで分けてつくってmainのcppでインクルードしますよね。 VC++ MFCも 「C++クラスの追加」 でウィザードを利用してあるクラスAを作成てみまして、わかる方にはわかるでしょうけど、もちろん以下のように出力されました。 A.h------------------ #pragma once class A { public: A(void); public: ~A(void); }; A.cpp---------------------- #include "A.h" #include "StdAfx.h" A::A(void) { } A::~A(void) { } そしてとりあえず、その状態で何も手を加えずにとりあえずコンパイルにかけてみたところいきなり以下のようなエラーが出ました。 error C2653: 'A' :識別子がクラス名でも名前空間名でもありません。 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません warning C4508: 'A' : 関数に戻り値の型が指定されていません。戻り値を void 型と見なします。 error C2653: 'A' : 識別子がクラス名でも名前空間名でもありません fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します 何も手を加えていない状態でこのようなエラーが出るということは、どこかでこのhやcppをインクルードする必要があるのだろうとは思います(でもそういう類のことはウィザードで作成した際に、VC++が自動でコーディングしてくれたりしないのでしょうかね...)。 むしろ、MFCでこのような単純なC++クラスを作ること自体があまり好まれないことなのでしょうか。 もちろんこのクラスを作っていってから、ある処理をさせていこうと思っているので、自分としては以前から行っていたC++のようにコーディングしていきたいと思うのですが、もし好ましくないようならどのファイルにMFC的ではない、ただのC++的なクラスを定義したりすればよろしいのでしょうか。 もしくは、好ましくなくても何らかの対処方法があれば教えていただきたく思います。 Webで調べても MFCクラスの作成などのことしか書いてないので、ちょっとわからなくて困っています。よろしくお願いします。

  • Visual Studio C++ と Pro*C/C++について

    Visual Studio 2008とPro*C/C++を使ってOracleのDBを操作するシステムを考えています。 Oracleのバージョンは10gを予定しています。 Visual Studioが最新バージョンのため、Pro*C/C++のプリコンパイ ラがサポートしていないという懸念があります。 問題ないでしょうか? もし問題があればOracleを11gもしくは、Visual Studioを2005にすれ ばいいでしょうか? 教えてください。 よろしくお願いします。

  • C++で解りません。

    C++で #include <iostream.h> int main(void) { int x; int y; cout << "xを入力してください:"; cin >> x; cout << "yを入力してください:"; cin >> y; cout << "x+yは" << x + y << "です。\n"; return 0; } ----------- で、 エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) エラー E2206 a.cpp 19: 不正な文字 ' ' (0×8140) とでます。どこがおかしいのか解りません。

  • Visual C++のビルドで

    こんにちは。VC++の初心者です。 今MFCアプリケーションでシングルドキュメントで「ユニコードライブラリをしようする」をチェックなしで簡単なプログラムを作ったのですが、HelloVCView.cppファイルの中で、 void CvdclsView::OnDraw(CDC* pDC)  //■変更 /*pdc*/ → pDC { ・・・   pDC->TextOut(0,0,"Hello,VC++"); }     と本に書いてあるとおり変更して、ビルドしたところ、 1>c:\documents and settings\・・\my documents\visual studio 2005\projects\vdcls\vdcls\vdclsview.cpp(51) : error C3872: '0x3000': この文字を識別子で使用することはできません 1>c:\documents and settings\・・\my documents\visual studio 2005\projects\vdcls\vdcls\vdclsview.cpp(52) : error C3646: '    ' : 不明なオーバーライド指定子です といった表示がでてしまい、ビルドできません。最初のほうはこれでビルドできたのですが、最近になってこのように新しく作ってビルドするとこのような表示が出てしまいます。このエラー表示をダブルクリックしたら上のOnDraw関数のところに移動しました。設定の箇所をいじったつもりはないのですがもしかしたらそのようなミスがあったかもしれません。 この0x3000とは何でしょうか?どのようにすればこのような問題が解決するのでしょうか。変な質問かもしれませんが、よろしくお願いします。 ちなみにVisual Studio 2005 Academic Editionを利用しています。

専門家に質問してみよう