人に聞けない痔の悩み、これでスッキリ >>

過去にVisual Studio C++ 6.0 で作成したプロジェクトを、Visual Studio C++ 2005に変換し、ビルドしてみたところ、イテレーターに関する操作をしているところでエラーが出ました。

---------- ソースの一部抜粋 ここから -------------
vector<char> array; // int型の動的配列

arrayに要素をpush_backする処理

while( it && it != array.end() ) // 末尾要素まで
{
cout << *it << endl; // *演算子で間接参照
++it; // イテレータを1つ進める
}
---------- ソースの一部抜粋 ここまで -------------

上記のwile文のところで以下のようなエラーが発生します。

---------- エラーメッセージ ここから -------------
error C2676: 二項演算子 '&&' : 'std::_Vector_iterator<_Ty,_Alloc>' は、この演算子または定義済の演算子に適切な型への変換の定義を行いません。(新しい動作; ヘルプを参照)
1> with
1> [
1> _Ty=char,
1> _Alloc=std::allocator<char>
1> ]
---------- エラーメッセージ ここまで -------------

とりあえず、"while( it && it != array.end() ) "を"while( *it!=NULL && it != array.end() ) "とするとエラーはでなくなりましたが、なぜもとのように書いてはダメなのかがさっぱりわかりません。
そもそも、itと*itでは、示す内容が違っているので、これでは解決になっていないのでは、という気もします。
ヘルプを見ても、VS6.0とVS2005でvectorやiteratorの動作が変わっていることが読み取れず、困っています。
どなたかご教授ください。

A 回答 (4件)

> イテレータのインスタンスを作るときに


> it=NULL;
> としておいて、後から他のイテレータの値を代入する、
> というようなことはできないのでしょうか?

iteratorはポインタではありませんから NULLの代入は合法ではありません。
    • good
    • 0
この回答へのお礼

いろいろとご教授いただき、ありがとうございました。
「iteratorはポインタみたいなもの」とイメージしていたのですが、ポインタと同じ用に扱えない部分もあるのですね。
自分でもこのあたりを再確認してみます。

長くお付き合いいただき、本当にありがとうございました。

お礼日時:2007/08/05 19:14

iteratorはコンテナ内のどこか1要素またはendを示します。


ヒント1: end は"最後の要素"・・・ではありません。
ヒント2: コンテナが空のとき、begin() == end()になる。

ポインタのようなもの、と解釈されても結構ですが
即物的なものではなくて、概念的な(コンテナ内のどこかを指す)もの、
と解釈されたほうが良いと思いますよ
    • good
    • 0

>> itが0/非0かを調べることに何の意味もありません。


> すみませんが、なぜ意味が無いのか、説明をいただけないでしょうか。

vectorの要素が空のとき、array.begin() == array.end() です。
なので while ( it != array.end() ) だけで十分。

この回答への補足

納得しました。ありがとうございました。

ちなみに、イテレータのインスタンスを作るときに
it=NULL;
としておいて、後から他のイテレータの値を代入する、というようなことはできないのでしょうか?

質問ばかりになってしまい、申し訳ありません・・・

補足日時:2007/08/05 16:31
    • good
    • 0

もともとのコード:


while( it && it != array.end() )
が間違ってます。
itが0/非0かを調べることに何の意味もありません。

この回答への補足

> itが0/非0かを調べることに何の意味もありません。

すみませんが、なぜ意味が無いのか、説明をいただけないでしょうか。
itがNULLになることは無いのでしょうか?
不勉強で申し訳ありません。

補足日時:2007/08/05 16:08
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC++ vectorのbeginについて

VC++2010にて下記コードのビルドは通るのですが、
vVecotrInt, vVectorIntPtrの要素数0のとき、iptr代入時に
Debug assertaion Failed! vector iterator not dereferencableとなります。
そもそもbegin()はイテレータなので、ポインタに代入しようとしていることが間違いかと思うのですが。

質問1.int* iptr = ~ ではなく、std:vector<int>::iteratorとすれば、
    要素数が0でもエラーがおきません。この違いは何でしょうか?

質問2.そもそもイテレータをポインタに代入して何か得することがあるんでしょうか?
    ただイテレータとポインタは同じようなものだと思って、コーディングしてるだけなんでしょうか・・・

コード:
// vVectorIntの要素を間接参照して(参照先はint)、そのアドレスをポインタに格納
std::vector<int> vVectorInt;
int* iptr = &*vVectorInt.begin(); // ここでvector iterator not dereferencable

// vVectorIntPtrの要素を間接参照して(参照先はint*)、ポインタに格納
std::vector<int*> vVectorIntPtr;
int* iptr = *vVectorIntPtr.begin(); // ここでvector iterator not dereferencable

// vVecotrIntPtr2の要素数0のときでも、イテレータを使えば問題ない
std::vector<int*> vVectorIntPtr2;
std::vector<int*>::iterator itr = vVectorIntPtr2.begin();

VC++2010にて下記コードのビルドは通るのですが、
vVecotrInt, vVectorIntPtrの要素数0のとき、iptr代入時に
Debug assertaion Failed! vector iterator not dereferencableとなります。
そもそもbegin()はイテレータなので、ポインタに代入しようとしていることが間違いかと思うのですが。

質問1.int* iptr = ~ ではなく、std:vector<int>::iteratorとすれば、
    要素数が0でもエラーがおきません。この違いは何でしょうか?

質問2.そもそもイテレータをポインタに代入して何か得することがあるん...続きを読む

Aベストアンサー

まずbegin()関数は反復子(イテレータ)を返すことを理解してください。
イテレータはポインタとは異なりますが、単項*演算子を使ってその要素を取り出すことができます。
これを元にコードを解釈すると、
std::vector<int> vVectorInt;
int* iptr = &*vVectorInt.begin();
のvVectorInt.begin() はintを要素とするベクタのイテレータ。
従って*vVectorInt.begin();はその要素であるintデータそのものです。
iptrはintへのポインタであるので、その要素であるintデータにアドレス演算子&を使用することによってアドレスを取得しています。
ベクタの要素数が0の場合、begin()は最終要素へのイテレータend()に一致し、無効なデータを指し示します。
従って、*vVectorInt.begin();は無効データとなり、not dereferencableというエラーが発生します。

std::vector<int*> vVectorIntPtr;
int* iptr = *vVectorIntPtr.begin(); // ここでvector iterator not dereferencable
も同様。

std::vector<int*> vVectorIntPtr2;
std::vector<int*>::iterator itr = vVectorIntPtr2.begin();
これはイテレータをとってきているのであって、イテレータを使った要素の取り出しは行っていません。
要素数0の場合、*itrを使えばnot dereferencableが派生します。

ベクタに限らずSTLコンテナではend()に一致するイテレータで要素をアクセスしてはいけません。

>質問1.int* iptr = ~ ではなく、std:vector<int>::iteratorとすれば、
> 要素数が0でもエラーがおきません。この違いは何でしょうか?
根本的な勘違いをしていると思います。
STLコンテナは要素数0でもイテレータを使用できますが、そのイテレータを使って要素を使用するにはイテレータが有効なデータを指している必要があります。そのためにはend()と一致していないことを確認する必要があります。

> 質問2.そもそもイテレータをポインタに代入して何か得することがあるんでしょうか?
> ただイテレータとポインタは同じようなものだと思って、コーディングしてるだけなんでしょうか・
提示されたコードはイテレータをポインタに代入しているわけでは有りません。
イテレータを使って要素のアドレスを取得しているだけです。

#2の補足
>イテレータだったら要素数を気にせずアクセスできるのに、
>アドレスを取得するには要素数を気にしなきゃいけないって、
アドレスを取得するのに要素数を気にしなきゃいけないのではなく、イテレータが有効なデータを指しているかを気にしなきゃいけないのです。
そもそもSTLではポインタを使用する必要はなくてイテレータを使用すれば事足ります。
ポインタを取得しているのはSTLを使用していないcで書かれた古いコードに配列を渡すために使用していると思われます。

>利点がいまいちわからないです・・・
イテレータを使用すれば、コンテナの種類(ベクタ、リスト等)によら同じアルゴリズムで処理を行うことができます。

まずbegin()関数は反復子(イテレータ)を返すことを理解してください。
イテレータはポインタとは異なりますが、単項*演算子を使ってその要素を取り出すことができます。
これを元にコードを解釈すると、
std::vector<int> vVectorInt;
int* iptr = &*vVectorInt.begin();
のvVectorInt.begin() はintを要素とするベクタのイテレータ。
従って*vVectorInt.begin();はその要素であるintデータそのものです。
iptrはintへのポインタであるので、その要素であるintデータにアドレス演算子&を使用することによってア...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QLPCWSTRとchar

質問なのです・・・

現在、私は[Visual Stdio.Net 2005]を使って、C++のプログラミングをしようと思いまして、今日参考書を見てやってみたのですが、

charの配列を使って、文字列を格納しそれを使おうとしたら、LPCWSTRのキャストが必要というエラーがでました。
参考書だと普通に通るらしいのですが・・・Visual Stdio.Net 2003と2005の違いなのでしょか?わかる方教えていただけませんでしょうか??

Aベストアンサー

補足です。
2005デフォルトのUNICODEを変更する方法は
プロジェクト->プロパティ->構成プロパティ->全般 の中にある
文字セットを[Unicode 文字セットを使用する]から[マルチバイト文字セットを使用する]
に変更することで可能です。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Qfatal error LNK1120: 外部参照 1 が未解決です

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
  char tel[20];
  char address[20];
};

void message( void );
void input( FILE *fp, int cnt , struct meibo *a, int *end );

void main( void )
{
  struct meibo a[20];
  FILE *fp;
  int cnt, end;

  if( (fp=fopen( "meibo.dat", "w" ) ) == NULL ){
    printf( "Can not open the meibo.dat.\n" );
    exit( 1 );
  }

  message();

  fprintf( fp, "番号, 名前, TEL, 住所\n" );
  fflush( fp );

  cnt = 0;
  end = 0;
  while( end == 0 ){
    input( fp, cnt, &a[cnt], &end );
    cnt++;
    fflush( fp );
    if( cnt == 20 ){
      printf( "人数が一杯です.終了します.\n" );
      end = 1;
    }
  }
  fclose( fp );
}

void message( void )
{
  printf( "名前, TEL, 住所, endを入力してください.\n" );
  printf( "継続の時はend=0," );
  printf( "中止の時は,end=1と入力してください.\n" );
}

void input( FILE *fp, int cnt, struct meibo *a, int *end )
{
  printf( "名前-->" );
  scanf( "%s", a->name );
  printf( "TEL -->" );
  scanf( "%s", a->tel );
  printf( "住所-->" );
  scanf( "%s", a->address );
  printf( "Exit? Continue:0 Exit:1 -->" );
  scanf( "%d", end );
  printf( "\n" );
  fprintf( fp, "%2d, %s, %s, %s\n",
    cnt+1, a->name, a->tel, a->address );
}

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
...続きを読む

Aベストアンサー

http://www.a.math.ryukoku.ac.jp/~hig/course/compsci2_2005/man/faq.html
にある現象と同じではないでしょうか、一度お試しください。

QC++のfor文について

C++では

for ( int i = 0, j = 0; i < 10; i++ )
{

}

みたいな感じでforのなかで変数の宣言ができます。

ところで上の例ですとint型のiとjを2つ宣言していますが、
もしint型とchar型を宣言したい場合などは

char j;
for ( int i = 0; i < 10; i++ )
{

}


みたいにしないといけないのでしょうか?

for ( int i = 0, char j; i < 10; i++ )
{

}

みたいにできると思ってやったらエラーになってしまうので・・。

Aベストアンサー

★『for』文について
・『for』文は次のようになります。
 『for ( 初期化式 ; 条件式 ; 増減式 ){ … }』です。
 この3つの『式』は独立していますので省略などが出来ます。→3つ省略の可能(無限ループになる)
・最初の『初期化式』ですが、ここには1つの『式』しか書けません。→昔から。
・それで『C++』では『for』文の中にも変数の宣言子が記述できるように機能UP
 しました。が、記述できるのは、やっぱり1つの式だけです。この1つの式に
 『宣言子』が1つ付けれるだけなので複数の『宣言子』をカンマなどでは記述
 出来ません。→回答者 No.2 さんの『言語仕様』って事ですね。
・よって、回答者 No.1 さんの『回答へのお礼』みたいに『char j』は外で宣言
 するしかないでしょう。

余談:
・無限ループを構成するのに『while ( 1 ){ … }』が有名ですが、『for』文でも
 構成できます。→このとき、3つの式を省略します。
・つまり『for ( ; ; ){ … }』とします。
 このやり方の方が、警告メッセージなどが出ないため『すっきり』します。
・以上。おわり。

★『for』文について
・『for』文は次のようになります。
 『for ( 初期化式 ; 条件式 ; 増減式 ){ … }』です。
 この3つの『式』は独立していますので省略などが出来ます。→3つ省略の可能(無限ループになる)
・最初の『初期化式』ですが、ここには1つの『式』しか書けません。→昔から。
・それで『C++』では『for』文の中にも変数の宣言子が記述できるように機能UP
 しました。が、記述できるのは、やっぱり1つの式だけです。この1つの式に
 『宣言子』が1つ付けれるだけなので複数の『宣言子』...続きを読む

Q構文エラー";"が型の前にありませんとは、どうしたら解決できるのですか。

キーボードから正の整数を読み取り、n個の奇数を加算しディスプレイにかきだすプログラムです。;が型の前に必要というエラーがずっとでてきて、でも足りないところはわからないのですが、何が違うのでしょう??もうわけがわからなくて困ってます。お願いします。

/*演習1-3*/
#include<stdio.h>
int main()
{
int i;
int n;
int sum=0;

printf("%d¥n",n);

for (i=1;i<=n;i+=2);
int scanf("%d",&n);
sum+=i;
printf("1+2+...+n=%d\n",sum);
return 0;
}

Aベストアンサー

(1) #includeの次に半角スペースがない。
(2) 変数n を初期化していない。
(3) printf文の\(半角文字)が¥(全角文字)になっている。
(4) for文の最後に不要な ; が付いている。
   ただし、これは、コンパイルエラーにはならない。

これらを修正すると、以下のようになります。
インデント(字下げ)は全角スペースを使用しているので、
そこはTABとかに直して使ってみてください。


#include <stdio.h>

int main()
{
 int i, m, n, sum;
 
 printf("正の整数(最大32767)を入力してください >");
 scanf("%d\n", &m);
 
 printf("0~%dの奇数の合計を計算します\n", m);
 
 sum = 0; /* 奇数の合計 */
 n = 0; /* 奇数の数 */
 for(i=1; i<=m; i+=2) {
  sum += i;
  if( i==1 ) {
   printf("%d",i);
  } else {
   printf("+%d",i);
  }
  n++;
 }
 
 printf("=%d\n", sum);
 printf("0~%dまでの奇数の数は%dで、合計は%dです\n",m,n,sum);
 
 return(0);
}

(1) #includeの次に半角スペースがない。
(2) 変数n を初期化していない。
(3) printf文の\(半角文字)が¥(全角文字)になっている。
(4) for文の最後に不要な ; が付いている。
   ただし、これは、コンパイルエラーにはならない。

これらを修正すると、以下のようになります。
インデント(字下げ)は全角スペースを使用しているので、
そこはTABとかに直して使ってみてください。


#include <stdio.h>

int main()
{
 int i, m, n, sum;
 
 printf("正の整数(最大32767)を入力...続きを読む

Q【VC+ 2005】CStringは使えないのでしょうか?

VC++2005超初心者です。
ちょっとした案件でVC++6.0から
2005に変えるということになりました。

現在VC++2005を利用して、ちょっとしたソースを書いていますが
VC++6.0でしようしていたCStringが利用できなくて困ってます。
例:CString aaa;
と宣言したら、CStringを認識してくれません。

CStringって、使えないのでしょうか?
なにかをincludeとかするべきなのでしょうか?
多分、本当に超簡単な問題かも知れませんが、よろしくお願いします。

Aベストアンサー

VC++2005無料版にはMFCはついていないのでCStringは使えません
有料版なら使えます

Q【C++/CLI】String型文字列の位置を指定して値を取り出す

VC++2005、.NET2.0、C++/CLIにてWindowsアプリを作成しています。

String型に格納された文字列の、位置を指定して値を取り出すには、
どのような方法を用いればよいのでしょうか?
基本的な質問で申し訳ありませんが、ご教示よろしくお願い致します。

例)
String^ st = "abあいcde";
//四番目の値を取り出す⇒「い」を取り出す

Aベストアンサー

こうですか?

String^ st = "abあいcde";
String^ st2 = st->Substring(3, 1);

あとこんな方法も・・・
String^ st = "abあいcde";
array<wchar_t>^ ary = st->ToCharArray();
wchar_t ch = ary[3];

QC++でのクラスオブジェクトの破棄

こんにちは。

C++では、プログラムの終了時に、全てのクラスオブジェクトは、デストラクタが呼び出されて破棄されますが、プログラムの途中で、クラスオブジェクトを明示的に破棄する方法はあるのでしょうか?

例えば、new演算子によってメモリを動的に割り当てたポインタなら、delete演算子で破棄できますが、
クラスオブジェクトにdelete演算子は使えないようです。

何かいい方法を知っておられる方がいらっしゃれば、是非アドバイスを頂きたいと思います。

Aベストアンサー

ClassA *p = new(buf) ClassA;

ClassA *p = new ClassA;
の意味は違います. 後者はメモリを割り当てますが, 前者ではメモリの割り当ては行われません. placement new なんかで調べてもらうといいかな.


人気Q&Aランキング