構造体の初期化 – プログラミング – Home

通知
すべてクリア

[解決済] 構造体の初期化


亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

struct Test {
int a;
CString b;
};

Test test[] = {
{ 1, _T(1), },
{ 2, _T(2), },
{ 3, _T(3), },
{ 4, _T(4), },
};

という構造体初期化の試作コードを入れてみたところ、
VC2005では問題無くコンパイルが通りますが、
VC6では
'const int' から 'struct Test' に変換することはできません。
'char [2]' から 'struct Test' に変換することはできません。
といったエラーがズラズラ出てきます。

これはなにかVC6時代の制限でもあるのでしょうか?
それとも、このような初期化自体が正しい方法ではないのでしょうか?


引用未解決
トピックタグ
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

struct Test {
int a;
LPCTSTR b;
};
にすれば通ります。

VC6は構造体初期化時に型変換できないのかな?


返信引用
Jason
 Jason
(@Jason)
ゲスト
結合: 16年前
投稿: 26
 

VC6など低レベルコンパイルの問題でしょう?

実はCStringもポイントですけど。。。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

情報ありがとうございます。
この構造体の初期化自体は間違った方法ではなく、
やはりVC6のコンパイラに制限があるのですね。

CStringをLPCTSTRに置き換えると確かに通りました。
これだとインスタンス生成後に文字列を変更する作業がかなり面倒そうですが、
現在のところは文字列自体は変更することは無く、
仕様上VC6でもコンパイルが通るようにしておかなければいけないため、
この方法で対応しておこうと思います。


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

以前経験したことあるな。

言語的にどういう規則なのかは知らない。

うろ覚えなので以下で成功するのか不明。VC6が使えないので確認しない。
生成されるコードがVC2005と同等に最適化されたものになるのかどうかは知らない。

解決案 1

struct Test {
int a;
CString b;
#if VC6
Test(int foo, LPCTSTR bar) : a(foo), b(bar) { }
#endif
};

解決案 2

#if VC6
xCString(x) CString(x)
#else
xCString(x) x
#endif

Test test[] = {
{ 1, xCString(_T(1)) },
{ 2, xCString(_T(2)) },
{ 3, xCString(_T(3)) },
{ 4, xCString(_T(4)) },
};


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

情報ありがとうございます。

解決案1のように

struct Test {
int a;
CString b;
Test(int foo, LPCTSTR bar) : a(foo), b(bar) { }
};

Test test[] = {
{ Test(1, _T(1)), },
{ Test(2, _T(2)), },
{ Test(3, _T(3)), },
{ Test(4, _T(4)), },
};

と書いてみたところ、VC6では通りましたが、今度はVC2005のほうで
「ユーザー定義のコンストラクタを含む型はアグリゲートではありません」
というエラーが出るようになりました。
初期化方法自体もコンパイラの種類で分けなくてはいけないのでしょうか。

解決案2のほうは、VC6上で

struct Test {
int a;
CString b;
};

Test test[] = {
{ int(1), CString(_T(1)), },
{ int(2), CString(_T(2)), },
{ int(3), CString(_T(3)), },
{ int(4), CString(_T(4)), },
};

と明示的に型を明示してもエラーは消えませんでした。


返信引用
ISLe
 ISLe
(@ISLe)
ゲスト
結合: 18年前
投稿: 38
 

VC6はC++の規格が曖昧だった頃に作られた古い処理系なのでその辺りの問題は2005以降
はコンパイラ毎に区別する必要は無いと思います。


返信引用
まえだ
 まえだ
(@まえだ)
ゲスト
結合: 17年前
投稿: 10
 

> インスタンス生成後に文字列を変更する作業がかなり面倒そう

こんなのどうですか?

struct Test {
int a;
CString b;

Test(int aa, LPCTSTR bb)
{
a = aa;
b = bb;
}
};

Test test[] = {
Test(1, _T(1)),
Test(2, _T(2)),
Test(3, _T(3)),
Test(4, _T(4)),
};


返信引用
まえだ
 まえだ
(@まえだ)
ゲスト
結合: 17年前
投稿: 10
 

ごめんなさい。既出でしたね。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

ちょっとトラブっていて返答が遅れてしまいました。
ISLeさん、まえださん、情報ありがとうございます。

Test test[] = {
Test(1, _T(1)),
Test(2, _T(2)),
Test(3, _T(3)),
Test(4, _T(4)),
};

のコンストラクタを使う方法だとVC6でもVC2005でも通りました。
2008/10/27(月)10:07:47の「アグリゲートではありません」という
エラーが出たときと同じではと思って前の書き込みを再度読んでみたところ、
コンストラクタを{}で囲ってしまっていました。
VC6で通ってしまっていたので気づきませんでした(恥)。

ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました