C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: [VC++9.0] VS2005→VS2008変換後エラー


(過去ログ 92 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■54654 / inTopicNo.1)  [VC++9.0] VS2005→VS2008変換後エラー
  
□投稿者/ AllOutAttack (1回)-(2010/10/28(Thu) 16:43:54)

分類:[C/C++] 

分類:[C/C++]

はじめまして、お世話になります。
現在、VisualStudio2005→VisualStudio2008へソリューションを変換し、
ビルドを通す際のビルドエラーで悩んでおります。

ソースファイルは元々VC++6.0のMFCで作成されたものを、
過去にVisualStudio2005(VC++8.0)に変換して修正を加えていたようで、
今回はVS2005からVS2008(VC++9.0)へ変換を行うことになりました。

手順としてVS2005のソリューションファイルをVS2008で開き、
変換マネージャーに従ってVS2008形式への変換を行った後、
ビルドを通そうとすると下記のエラーが発生します。

VC++の経験自体が少ないため資料を探し、色々と試しているのですが、
内容的にVSのutilityが間違っているとは思えず、
先の見えない状態に陥っています。

申し訳ありませんが、ご助力いただけないでしょうか?

■エラー内容
error C2558: class 'std::auto_ptr<_Ty>' : コピー コンストラクタが使用できないか、'explicit' として宣言されています。
c:\program files\microsoft visual studio 9.0\vc\include\utility
※エラー箇所に飛んでみると、utility内のpairのコピーコンストラクタを指しています。

pair()
: first(_Ty1()), second(_Ty2())
{ // construct from defaults
}

pair(const _Ty1& _Val1, const _Ty2& _Val2)
: first(_Val1), second(_Val2)
→この部分 { // construct from specified values
}



■環境
Visual Studio 2008 Pro

ソリューション構成

aaa.sln
xxx.vcproj→画面に表示する内容を処理するソース
yyy.vcproj→日本語画面用の画面ソース
zzz.vcproj→英語画面用の画面ソース

■試したこと
・下記のようにmapとqueueにpairを入れ込んでおり、
 pairをvectorに入れ込む際にエラーが発生するという情報があったため、
 該当箇所をコメントアウトしてビルド→エラーのまま内容も変わらず。

 std::map<CString, std::pair<CFile, CString>> m_File;
 std::queue<std::pair<int, CString> > m_Queue;

・別プロジェクトを作成し、
 pairを使用している変数宣言と同じ形の記述でビルド→正常にビルド

・別プロジェクトを作成し、
 ヘッダーファイルとソースファイルをコピーしビルド→エラーのまま内容も変わらず。


引用返信 編集キー/
■54667 / inTopicNo.2)  Re[1]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ 774RR (556回)-(2010/10/28(Thu) 21:35:56)
auto_ptr が explicit だ、というエラーメッセージが pair のところで出ているだけだから
とりあえず見るべきは auto_ptr であって pair をこねくりまわしても無駄な努力。

で、言語規格書によれば auto_ptr のところで explicit が現れるのは
explicit auto_ptr::auto_ptr(T* p=0) throw() { ... } だけであるから、
おそらくスレ主のところでは何らかの形で
「生ポインタから暗黙の変換コンストラクタを経由して auto_ptr にしようとする」
コードがあるものと推定される。
(その経路がたまたま pair のところで発現しているだけ)

それ以上は発言内容から読み取れないので、もう少し追いかけて味噌。
繰り返すが、追いかけるべきは auto_ptr を使っているところだよ。
# 現代 C++ なら auto_ptr みたいな非推奨機能は捨て捨て。
引用返信 編集キー/
■54683 / inTopicNo.3)  Re[2]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ AllOutAttack (2回)-(2010/10/29(Fri) 09:44:42)
>774RR様

ご助言ありがとうございます。
ご指摘の通り変換コンストラクタを使用している箇所があり、
該当箇所を取り除いてビルドすると正常にビルドが行えました。

auto_ptrは非推奨機能ということで、
この際使用しないように変更を加えようかと考えています。
一度試してみて、経過を報告させていただきます。

引用返信 編集キー/
■54691 / inTopicNo.4)  Re[3]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ 774RR (558回)-(2010/10/29(Fri) 11:22:14)
auto_ptr は言語規格書の確定の際に紆余曲折があってモメた代物だ。
VC++6 は言語規格書確定前の処理系で auto_ptr が [確定済み仕様] に合致してない。

auto_ptr<int> a(new int);
auto_ptr<int> b(a); // としたとき

[言語規格合致動作] (VS2005 以後はこの動作)
a は所有権を失う。
a->get() とすると NULL が得られなければならない

[VC++6 の古い動作]
a は所有権を失う。
a->get() としたら所有権の無いポインタ値が得られる

というわけで VS2005 へコンバートする際には auto_ptr の挙動が変更されており、
本来なら [ そのときに ] auto_ptr 関連は全面的再検証が必要だった。

変換コンストラクタが explicit なのは VC++6 の頃からのはずなので、
> 変換コンストラクタを使用している箇所があり、
もしその箇所が最初からあれば VC++6 の時にもこのエラーは出ているはず。
ということは最近になって書き換えたか何かだと推定されるのだが。
手で書き換えているならよし、コンバートの際にツールが書き換えてしまったのなら激マズ。

まあなんにせよ auto_ptr はコンテナに入らないとか配列を相手に出来ないとか
俺は一度も実用に供したことが無いな。 boost::shared_ptr のほうが100倍まし。

VS2010 ならばこっち
http://blogs.wankuma.com/episteme/archive/2010/08/04/192001.aspx

引用返信 編集キー/
■54700 / inTopicNo.5)  Re[4]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ AllOutAttack (4回)-(2010/10/29(Fri) 14:16:09)
>774RR様

auto_ptrが非推奨になった理由まで教えていただき、ありがとうございます。
勉強になります。

> もしその箇所が最初からあれば VC++6 の時にもこのエラーは出ているはず。
> ということは最近になって書き換えたか何かだと推定されるのだが。
> 手で書き換えているならよし、コンバートの際にツールが書き換えてしまったのなら激マズ。

コンバート前のソースと比較したところ、
自動で変換されたものではありませんでした。
ということは、そもそもVS2005でビルドが通っていたソースなのか気になってきました…
手元に2005がないので、試そうにも試せないですが…

そのあたり自体があやしい気がしてきました…
まずは、本当に最新のソースなのかを再確認してみます。

また、順番が前後しますが、boostについてもアドバイスありがとうございました。
boost自体はインストールしているので、ソースの確認後にshared_ptrを採用するのか検討させていただきます。

引用返信 編集キー/
■54714 / inTopicNo.6)  Re[5]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ AllOutAttack (6回)-(2010/10/29(Fri) 18:28:03)
2010/10/29(Fri) 18:29:39 編集(投稿者)

途中経過です。

結局いただいたソースは一応正しいようでしたが、
元々VS2005より以前のソースをVS2005へコンバートだけした状態で渡されたようです…

auto_ptrについては、boost::shared_ptrへ変更することで対応を行いました。

auto_ptrについては無事解決できたのですが、
次にまた、行き詰っております…

次のような仮想配列の中でCFileクラスを持ったメンバを使用していると、
エラーとなってしまいました。
調べてみると、CObjectクラスを基本クラスに持つ派生クラスで
代入演算子、コピーコンストラクタを使用する場合に、
CObjectクラスの代入演算子、コピーコンストラクタはprivateで定義されているため
派生先に代入演算子、コピーコンストラクタを作らないとのことでした。

理由についてはなんとなく理解できましたが、
どのように修正すればよいのかがよくわかっておりません。
CFileを継承して自分で実装したりするのでしょうか?
もし、一般的な修正方法等があればお教えくださいませんでしょうか?

■仮想配列
std::map<CString, std::pair<CFile, CString>> m_Files;

■エラー内容
error C2248: 'CObject::CObject' : private メンバ (クラス 'CObject' で宣言されている) にアクセスできません。




引用返信 編集キー/
■54718 / inTopicNo.7)  Re[6]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ 774RR (562回)-(2010/10/29(Fri) 22:12:31)
コンテナは入れる元のコピーを内部に保有するというのは認識おkだろうか?
例1:container.push_back(i); // i の複写を行い i はそのまま、コンテナは複写を保持する
例2:char* p=strdup(s);
container.push_back(p); // ポインタ値の複写がされるだけ
free(p); // コンテナが保持するポインタの先にある文字列は処分されてしまった
(コンテナに文字列のつもりで char * 生ポインタを入れるのはきわめて危険)
(コンテナに std::string を入れるのであれば適切)

であるから、そもそもコンテナに CFile を入れる、ということ自体がヘン。
CFile を複写するということに、当該コードの最初の作者は何を期待していたのか、それ次第で
どう解決すればよいかはまったく違う。

・ CFile で開いているファイルが複写される?
・読み書き位置やキャッシュが異なる新しいファイルハンドルが複写される?
・読み書き位置やキャッシュがまったく同一の、異なるファイルハンドルが複写される?
・メモリ上の単なるバイト列がコピーされる?
 単なるバイト列がコピーされても CFile としては役に立たない。
・それともまったく違う深遠な何か?
**stream がコピーできないのもそういう理由。

俺が妄想するに、そのコードはおそらく根幹設計が間違っている。
たぶん全面的に作り直すほうが安全で早く解決すると見た。
引用返信 編集キー/
■54752 / inTopicNo.8)  Re[7]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ AllOutAttack (7回)-(2010/11/01(Mon) 11:15:26)
>774RR様

土日は遠出していたため、返信できなく申し訳ありません。
また、コンテナについての説明ありがとうございます。

遅くなってしまいましたが、
プログラム全体でやりたいことと、
問題となっている箇所でやりたいことを記述させていただきます。

■全体の処理
@外部からデータ受信
A受信データを解析
B解析データを出力
※簡単にいってしまうとロガーです。

■問題箇所で行いたい処理
全体処理のBの一部分になります。
問題となっている仮想配列の使用目的としては、
Aの受信データを解析した際、内容によって出力ファイルを変更するため
出力先のファイル名をキーとしてCFile変数
(実際はpairでsecondに出力ディレクトリを持っていますが)を持ち、
複数のファイル操作を管理しようとしているようです。

※ロガーということで、データ出力のたびにOpen、Closeでなく、
 出力ファイルはOpenしっぱなしのイメージ?かもしれません。

もう少し、ソースの理解を深めたいとおもいます。

引用返信 編集キー/
■54797 / inTopicNo.9)  Re[8]: [VC++9.0] VS2005→VS2008変換後エラー
□投稿者/ AllOutAttack (8回)-(2010/11/02(Tue) 14:59:11)
2010/11/02(Tue) 15:01:12 編集(投稿者)

>774RR様

今まで少ない情報の中から色々とご助言していただき、ありがとうございました。
CFileに関しては、mapに持たせず別途arrayでメンバを作成し、
mapにはarrayのインデックス番号を値として持たせ、
arrayにアクセスするよう修正することにいたしました。

根幹から変えすぎると影響範囲が大きすぎたため、
センスの良い修正方法ではありませんが一応この方法で対応することにしました…

次の修正では設計からの見直しを提案してみます。

ひとまずこれで、タイトルの「VS2005→VS2008変換後エラー」については解決とさせていただきます。

ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -