- ベストアンサー
可変引数をconstで参照渡し
以下のようなクラスをconstの参照渡しでうけとる、可変引数を持つ関数を作りたいのですが、以下のようにしてもうまくいきません。 何か良い方法はないものでしょうか? template<class TT> class vector3{ public: enum{NUM=3}; TT x[NUM]; void Sum(const int num,...); }; template<class TT> void vector3<TT>::Sum(const int num,const ...){ int i,j; va_list list; va_start(list,num); for(i=0;i<NUM;i++){ x[i]=va_arg(list,&vector3<TT>).x[i]; } for(j=1;j<num;j++){ for(i=0;i<NUM;i++){ x[i]+=va_arg(list,&vector3<TT>).x[i]; } } va_end(list); }
- coronalith
- お礼率82% (87/106)
- C・C++・C#
- 回答数2
- ありがとう数3
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
残念ながらないです. 「...」に当てはまる引数はすべて右辺値に変換されます (同様に配列名や関数名も対応するポインタに変換される). ついでにいうと, 変換した後の値が nonPOD なクラス型だとその振る舞いは未定義であるとなっています. だから, 参照で渡すのは (クラスかどうかには無関係に) 不可能です. というか, ポインタで渡しちゃだめなの?
その他の回答 (1)
- titokani
- ベストアンサー率19% (341/1726)
試していませんが、どうせ書くなら > x[i]=va_arg(list,&vector3<TT>).x[i]; > x[i]+=va_arg(list,&vector3<TT>).x[i]; ではなくて、 x[i]=va_arg(list,vector3<TT>&).x[i]; x[i]+=va_arg(list,vector3<TT>&).x[i]; ではないかと。
お礼
ああそうでしたね^^; まちがえてました
関連するQ&A
- コンパイルエラー: LNK2001
今、ベクトル計算を簡単にするクラスを作ってみようとしています。 //vector3.h template<class TT> class vector3{ public: enum{NUM=3}; TT x[NUM]; void set(const TT *vv)void set(const TT *vv){ int i; for(i=0;i<NUM;i++){ x[i]=vv[i]; } } }; のように、set関数をクラスの中に書いていると問題無いのですが、以下のように、 //vector3.h template<class TT> class vector3{ public: enum{NUM=3}; TT x[NUM]; void set(const TT *vv); }; //test.cpp #include"vector3.h" template<class TT> void vector3<TT>::set(const TT *vv){ int i; for(i=0;i<NUM;i++){ x[i]=vv[i]; } } と、cppファイルの中に書き換えると以下のようにエラーが出るようになります。 error LNK2001: 外部シンボル ""public: void __thiscall vector3<double>::set(double const *)" (?set@?$vector3@N@@QAEXPBN@Z)" は未解決です。 fatal error LNK1120: 外部参照 1 が未解決です。 これはいったい何故なのでしょうか? 使用しているのはVisualC++2008ExpressEditionです 宜しくお願いします。
- ベストアンサー
- C・C++・C#
- typeidと計算コスト
今、以下のようなクラスの関数を作っているのですが、typeidはプログラム実行時に実行される関数という扱いなのでしょうか? それとも、コンパイル時に実行されるマクロ関数的な扱いのものなのでしょうか? もし、プログラム実行時に実行されるなら、コンパイル時にTTの種類によって内容をコンパイルする内容を変更すると言うことは不可能でしょうか? また、どうしても、プログラム実行時にしかできないのならと考え、 type_info ty=typeid(TT) と、代入してから判定してみようかとやってみたのですが、「error C2248: 'type_info::type_info' : private メンバ (クラス 'type_info' で宣言されている) にアクセスできません。」と表示され無理なようでした。 何か良い方法はないものでしょうか? template<class TT> class vector3{ public: enum{NUM=3}; TT x[NUM]; int GetMemberList(char *str,const int bufsize,char *format=0); }; template<class TT> int vector3<TT>::GetMemberList(char *str,const int bufsize,char *format=0){ int i,j; if(!format){ const int size=4; type_info format=new char[size]; if(typeid(TT)==typeid(int)){ strcpy_s(format,size,"%d"); } else if(typeid(TT)==typeid(double)){ strcpy_s(format,size,"%lf"); } else{ return(1); } } j=sprintf_s(str,bufsize,format,x[0]); for(i=1;i<NUM;i++){ j+=sprintf_s(str+j,bufsize-j,","); j+=sprintf_s(str+j,bufsize-j,format,x[i]); } if(format)delete [] format; return(0); }
- ベストアンサー
- C・C++・C#
- constについて
#include <iostream> using namespace std; class I { int *x; public: unsigned int size; I(){size=0;x=new int[size];} I(unsigned int i){size=i;x=new int[size];} ~I(){delete []x;} int &operator()(unsigned int i){return x[i];}//!!!! const int &operator()(unsigned int i) const{return x[i];}//???? }; void main() { I a(10); for(int i=0;i<10;i++)a(i)=i;a(2)=a(0); for(int i=0;i<10;i++)cout<<a(i); } この場合は//????はいらないと思いますが //????を定義することがありますがどんな場合でしょう //!!!!があるのにあったほうがいいのはどんな場合でしょう?
- ベストアンサー
- C・C++・C#
- 引数の可変
覚えたての引数の可変を使ってみた素人であります。(独学です 見よう見真似で書いた為、目茶苦茶だと思われます。 自分で簡単なexeファイルを作ってみていて 引数の可変が必要となったので付け足そうとしていたのですが、「引数の可変」部の他 意外にもfor文からもエラーが出ました(while使えば済む話なのですが) 今までfor文をあまり使わずwhile文ばかり使っていた為、for文の基本的な構文が失敗しているのかもしれません。折角だから使ってみようとした結果がこれです。 #include <stdio.h> #include <locale.h> #include "DxLib.h" #include <string.h> #include <stdarg.h> int i; ・・・略・・・ class CharsOut{ ____int ypixel; ____char *hangar; ____int size; ____int HowMany; ____int list; public: ____int CharsOuting(int HowMany,int ypixel,int size,...); }; int CharsOuting(int HowMany,int ypixel,int size,...){ ____va_start(list,HowMany); ____for (i=0;i<HowMany;i++){ ________printf("%s",va_arg(list,char *)); ____} ____va_end(list); ____return 0; } ypixel、size...といった変数等は気にしないでください。 成功していたらコードを足すつもりでした。 自分がやりたいことは、main関数から変数HowMany,*hangar等を受け取り 文字列*hangarを引数の分出力したいのであります。引数の可変は*hangarを何個か渡すつもりだったので使用しました。 こんな感じに使うつもりでしたc.CharsOuting(2,0,32,"I am ", "hangury"); ※リストは(int HowMany,int ypixel,int size,...)です ※ハングリーのスペルが違う等ということはとてつもなくどうでもいいことなのです。 自分で「main関数から*hangarを受け取り」と書いておきながらリストに*hangarがない時点でおかしいと思ってはいるのですが、記述の方法が分からないので書けません。 以下エラー (名前とか一部改変・不要な部分省略 1>------ ビルド開始: プロジェクト:(≡ω≡.), 構成: Debug Win32 ------ 1>コンパイルしています... 1>soucer.cpp 1>error C2040: 'i' : 'int' は 'int [5]' と間接操作のレベルが異なります。 1>error C2065: 'list' : 定義されていない識別子です。 1>error C2440: '=' : 'int' から 'int [5]' に変換できません。 1>配列型への変換はありませんが、参照またはポインタから配列への変換があります。 1>error C2446: '<' : 'int' 型から 'int *' 型への変換ができません。 1>整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。 1>error C2040: '<' : 'int [5]' は 'int' と間接操作のレベルが異なります。 1>error C2105: '++' には左辺値が必要です。 1>error C2065: 'list' : 定義されていない識別子です。 1>error C2065: 'list' : 定義されていない識別子です。 1>ビルドログは "file://c:\・・・\Debug\BuildLog.htm" に保存されました。 1>(≡ω≡.) - エラー 8、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== 文章能力なくて申し訳ありません。 ご回答頂ければ幸いであります。宜しくお願いします。 OS:WinXP コンパイラ:Visual C++
- 締切済み
- C・C++・C#
- コマンドライン引数を用いて。
コマンドライン引数を用いて足し算をさせるプログラムです。 class goukei{ public static void main(String args[]){ int i, count; int sum = 0; int a[]; count = args.length; for(i=0; i<args.length; i++){ int arg_i = Integer.parseInt(args[i]); sum = sum + arg_i; } System.out.println("引数の数は" + count); System.out.println("合計は" + sum); } } と考えたのですが、もっとこうしたほうがいいという部分があれば教えてください。 一応これでできているとは思うのですがイマイチ自信がありません・・・。
- ベストアンサー
- Java
- 可変個引数を使った関数で文字の長さを知りたい
可変個引数を使った引数を使って引数の文字列の長さを知りたいのですがどうすればいいのかわかりません。 DXライブラリを使って文字列の長さを測って文字をどこにおくのかを決めているため文字列の長さがわからないと困ってしまいます。 どのようにすれば可変個引数を使った引数の文字列の長さを測れますか? 大体以下のような感じで作っています。 void kai( int *x , int *y ); //文字列を改行する関数 int JC( unsigned char code ); //文字が1バイト文字 か 2バイト文字か判別する void mozi_show2( int x , int y , int xm , int yb , int color , int char_set , const char *s , ... ){ int i = 0; int xs = 0 , ys = 0; int m_color = color; char One[ 2 ]; //1バイト文字格納用 char Two[ 3 ]; //2バイト文字格納用 const char* p; va_list args; va_start( args , s ); p = s; while( *p != '\0' ){ switch( *p ){ case '%': p++; assert( *p != '\0' ); switch( *p ){ case 'd': DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%d" , va_arg( args , int ) ); //purintfと使い方はほぼ同じで左から文字を表示したいX座標・文字を表示したいY座標 //文字の色・文字の書式・格納用文字列・表示したいint型の数値をあらわしています xs += 16; /* xs += GetDrawFormatStringWidthToHandle( char_set , "%d" , va_arg( args , int ) ); 本来ならこの関数を使って文字列の長さを計る左から 文字列の書式・格納用文字列・長さを測りたいint型文字列 これを使うと別のものを計っているみたいで文字の長さがわからない 文字の長さってどうやって計るの? */ break; case 'f': DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%f" , va_arg( args , double ) ); break; case 'c': DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%c" , va_arg( args , char ) ); break; case 's': DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%s" , va_arg( args , const char* ) ); break; case '%': DrawFormatStringToHandle( x + xs , y + ys * yb , m_color , char_set , "%%" ); xs += GetDrawStringWidthToHandle( "%" , 1 , char_set ); break; } p++; break; default: if( JC( *p ) ){ Two[ 0 ] = *p; Two[ 1 ] = *( p + 1 ); Two[ 2 ] = '\0'; DrawStringToHandle( x + xs , y + ys * yb , Two , m_color , char_set ); xs += GetDrawStringWidthToHandle( Two , 2 , char_set ); p += 2; } else{ One[ 0 ] = *p; One[ 1 ] = '\0'; DrawStringToHandle( x + xs , y + ys * yb , One , m_color , char_set ); xs += GetDrawStringWidthToHandle( One , 1 , char_set ); p++; } break; } if( xs > xm ){ kai( &xs , &ys ); } } va_end( args ); } void zitu_draw( void ){ char *str = "%d個 OK"; int i = 12; mozi_show2( 100 , 100 , 300 , 15 , red_s , MG_14_0 , str , i ); //左から 文字を表示するX座標・文字を表示するY座標・文字を改行する文字列の長さ //改行した時のY座標の縦幅・文字色・文字の書式・表示したい文字列・%dに表示したいint型の値 }
- 締切済み
- C・C++・C#
- 可変引数について。
va_argを使う方法は知っているのですが、受け渡す引数の数を指定しない方法で、決まった型引数を任意数渡す方法はC言語(C++ではない)で実現できますか? char* test( n, str1, str2, str3, …任意数) nはint, str○ は const char* という形ならば、第二引数以降の引数を呼び出し元で n に与えてやれば、n回だけ va_arg(args, char*) を呼び出せばよいですが、 char* test2(str1, str2, str3, str4, …1つ以上の任意数) という形だと、引数の個数を取得できないためうまくできません。 実現不可能でしょうか?
- ベストアンサー
- C・C++・C#
- templateにの指定に従ったswitch
以下のような感じで、template TTの種類によって処理を変えたいのですがうまくいきません。 どの様にすればいいのでしょうか? 宜しくお願いします。 template<class TT> void vector3<TT>::GetMemberList(char *str,const int bufsize,char *format=0){ int i,j; if(!format){ switch(TT){ case int: format=new char("%d"); break; case double: format=new char("%lf"); break; } } }
- ベストアンサー
- C・C++・C#
- scanfでの可変引数
こんばんわ。 C言語で簡単な支出計算プログラムみたいなのを作ったのですが、自分の思ったようなプログラムが書けません。 #include<stdio.h> int main(int argc,char *argv[]){ int i; int n1; int a1,a2; int sum=0; puts("計算する日数を入力してください。"); printf("日数:"); scanf("%d",&n1); for(i=1;i<=n1;i++){ printf("%d日目:",i); scanf("%d",&a1); sum+=a1; } printf("【%d日間の支出】:%d円\n",i-1,sum); } 実行結果は以下のようになります。 計算する日数を入力してください。 日数:2 1日目:100 2日目:200 【2日間の支出】:300円 このプログラムだと1日に1つの支出しか計算してくれません。 1日で入力できる支出を複数にしたいのですが、つまり下のように 計算する日数を入力してください。 日数:3 1日目:100,150 2日目:200 3日目:300,150,1000 【3日間の支出】:1900円 のようにscanfで入力した数値を可変個の値にしたいのですが、 どのように実現したらよいでしょうか? scanf("%d,%d"&a1,&a2);のように2つにしてれやば複数にはできますが 必ず2個入力しないとエラーになってしまいます。 調べた所va_listという可変引数リストが使えそうなのですが、 scanfでどのように使えばよいのかわかりません。 ご教授よろしくお願いします。
- 締切済み
- C・C++・C#
- const参照メンバを含む要素のvector
久しぶりに趣味でプログラミングしてます。 const参照のメンバを含むオブジェクトを要素に持つvector って使えます? 下記はbcc32でコンパイルするとエラーが出ます。 _algobase.h 145:コンパイラは 'operator=' クラスの hoge を作成できない(関数 _STL::hoge * __copy<hoge *,hoge *,int>(hoge *,hoge *,hoge *,const random_access_iterator_tag &,int *) ) ちなみにv.clear();をコメントアウトするとコンパイルは通り実行も問題なくできます。 clear()の替わりにpop_back()としてもコンパイルは通り実行も問題なくできます。 コンパイラーのバグ?そもそもこんなことをしてはダメ? よろしくお願いします。 class hoge { public: hoge(const int &i):_i(i){}; virtual ~hoge(){}; operator int () const {return _i;} const int &_i; }; int main() { int i1=1; int i2=2; hoge h1(i1); hoge h2(i2); std::vector<hoge > v; v.push_back(h1); v.push_back(h2); v.clear(); std::vector<hoge >::iterator iter = v.begin(); while( iter != v.end() ){ std::cout << *iter << "\n"; ++iter; } return 0; }
- ベストアンサー
- C・C++・C#
お礼
そうですか、どうも有り難うございました。