トップページ⇒tech
1001コメント296KB

C++相談室 part54

■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v2006/10/30(月) 22:34:08
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE(VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

テンプレその他 >>2-15 付近参照

前スレ
C++相談室 part53
http://pc8.2ch.net/test/read.cgi/tech/1159340181/
0232デフォルトの名無しさん2006/11/06(月) 16:13:57
>>231
for_each()って事?
添え字がわかっているならoperator[]でアクセスできるけど
0233デフォルトの名無しさん2006/11/06(月) 16:17:03
関係ないけどメンバ変数が降順もしくは昇順にソートされているなら
lower_bound()も使える。
0234デフォルトの名無しさん2006/11/06(月) 16:41:44
>>231

template< class T, typename V > struct my_predicate
: public binary_function< T, V, bool > {
 bool operator()( T const & t, V v ) const {
  /* TODO:比較処理 */
 }
};

...

vector<T> vt;
vector<T>::iterator it = find_if( vt.begin(), vt.end(), bind2nd(my_predicate<T,int>(),1) );
0235デフォルトの名無しさん2006/11/06(月) 16:45:27
ある値を使いたいのですが、その値を1.2.5.10.20.50.100.200・・・・のように
出力したいのですがそのようなプログラムになるのでしょうか?よろしくお願いします。
0236デフォルトの名無しさん2006/11/06(月) 16:47:56
>>235
質問が抽象的すぎ
ある値がどこにあるのかとか。
それ以前に丸投げってやつは(ry
0237デフォルトの名無しさん2006/11/06(月) 16:53:08
>>235-236
たとえばある一次式のxの値に1.2.5.10.20.50.100.200・・・・と順にその答えを出したいのですが、
1.2.5.10.20.50.100.200・・・・をどうやって出力するのかってことかな?
0238デフォルトの名無しさん2006/11/06(月) 16:54:25
単に、数字をピリオドで区切っていくつも出力したいだけなのでは・・・
0239デフォルトの名無しさん2006/11/06(月) 17:06:33
順番に出力だとちょっと面倒だなぁ
0240デフォルトの名無しさん2006/11/06(月) 17:10:39
単に{1,2,5}の配列に*10しつづけながら出力するだけじゃないの?
0241デフォルトの名無しさん2006/11/06(月) 17:13:03
考え方はそれで良いと思うけど、プログラムにするとちょい面倒・・・
0242デフォルトの名無しさん2006/11/06(月) 17:15:24
それのどこが面倒なのか
0243デフォルトの名無しさん2006/11/06(月) 17:25:51
よくわからないけどこういうこと?

#include <stdio.h>

void main(void){
int x[] = {1, 2, 5};
int i;

for(i = 1; 1; i *= 10)
printf("%d.%d.%d.", x[0]*i, x[1]*i, x[2]*i);
}
0244デフォルトの名無しさん2006/11/06(月) 18:43:29
struct c
{
c(){cout << "c ctor" << endl ;}
//c( const c &obj ){cout << "c copy ctor" << endl ;}
~c(){cout << "c dtor" << endl ;}
} ;

c func( c obj )
{
cout << "func" << endl ;
return (obj) ;
}
で
func( c() ) ;
と実行すると
c ctor
func
c dtor
c dtor
c dtor

//をとってコピーコンストラクタを実装すると
c ctor
func
c copy ctor
c dtor
c dtor

コピーコンストラクタの定義の有無で
デストラクタの呼び出し回数が変わるものなのでしょうか?
0245デフォルトの名無しさん2006/11/06(月) 18:53:08
>>244
きちんとした実験結果があるのになぜ質問しているのか不明ですが、
現に変わってるでしょう?

なぜこういう動作になるかは、コピーコンストラクタがある場合と無い場合とで
引数(と戻り値)の受け渡しがどう変わるかを調べればわかると思います。
0246デフォルトの名無しさん2006/11/06(月) 19:00:08
for(;;) {
printf("%d.%d.%d.", x[0]*=10, x[1]*=10,x[2]*=10);
}
のほうがよくね?
0247デフォルトの名無しさん2006/11/06(月) 19:48:05
>>244
コンパイラはコピーを最適化して除去できるので
変わっても不思議ではない。実際、GCCではどちらも2回だった
0248デフォルトの名無しさん2006/11/06(月) 21:10:23
C++関係のサイトをみていると
"Move Semantics"
という単語がでてくるんですが、コレは
std::auto_ptrの様にオブジェクトの所有権が移動する
事を指している
という認識でいいんですか?
0249デフォルトの名無しさん2006/11/06(月) 21:13:57
>>248
文脈にもよるけど、たぶんC++0xの機能のこと。
その機能の目的はauto_ptrのような所有権の移動を楽に記述するような機能と思えば大体OK
0250デフォルトの名無しさん2006/11/06(月) 21:25:54
>>249
ありがとうございます。
具体的にどういう仕組みかわからないので、ググってきます
0251デフォルトの名無しさん2006/11/06(月) 22:32:39
>>244
それ、コンパイラ何使ってる?
コピーコンストラクタをユーザー定義するかどうかで
一時オブジェクトの有無が変わる理由がわからん。
02522442006/11/07(火) 01:04:15
>>245
変わってるんですが、なぜかわからなかったもので。
引数と戻り値の受け渡し時のコピーがらみかなとも思ったんですが
調べてもわからなかったもんで。

デストラクタが3回呼ばれるのが謎で
コピーコンストラクタの呼び出しをチェックしようとしたら
デストラクタが2回しか呼ばれなくなってわからなくなりました…

>>247
 GCCではどちらも2回なんですね。コンパイラ依存?

 VS2005 C++を使ってるんですが、デバッグ用なので
 最適化オプションは無効になってますが、
 その最適化とは違うことだとすると
 ユーザ定義のコピーコンストラクタがない場合のみ
 一時オブジェクトが2個作られてるって事でしょうか。調べてみます。

>>251
 VS2005 C++です。
 私もその理由がわからなくて悩んでます。
 >>247 の最適化による除去が濃厚そうですね。
0253デフォルトの名無しさん2006/11/07(火) 01:23:19
A := B | C | D
B = a | bc

みたなBNFをtemplate使って書いてみたいんですけどどうやって書けばいいの?
0254デフォルトの名無しさん2006/11/07(火) 01:45:09
一体全体どこにtemplateを使うって?
0255デフォルトの名無しさん2006/11/07(火) 02:04:10
>>253
つ[Boost.Spirit]
0256デフォルトの名無しさん2006/11/07(火) 02:04:34
>>251
ユーザー定義のデストラクタはあり、
ユーザー定義のコピーコンストラクタはない
バランスが取れてないのでVC++は除去しないと見た
ベンダに聞かないと分からんけどなw
0257デフォルトの名無しさん2006/11/07(火) 02:18:36
std::map<std::string, A *> m;
っていうコンテナ作りました。

これだと、Aを丸々コピーしなくても問題ないですよね?

あと格納したオブジェクトをoperator()を実装して呼び出せば
関数呼び出しのコストはかからないですよね?
0258デフォルトの名無しさん2006/11/07(火) 02:29:13
>>257
sizeof(A *)のコピーしか無いだろうが、ポインタの参照先については責任を持たなきゃならんな。


>あと格納したオブジェクトをoperator()を実装して呼び出せば
A::operator () () であろうが、void A::func()であろうが、所詮は同じ「関数」。
0259デフォルトの名無しさん2006/11/07(火) 10:02:19
>>253
ttp://p-stade.sourceforge.net/biscuit/index.html

typedef seq<
 chseq<'/','*'>,
 star_until< any, chseq<'*','/'> >
> c_comment;

std::string text("/* Hello, Biscuit! */");
if (biscuit::match<c_comment>(text)) {
 //...
}
0260デフォルトの名無しさん2006/11/07(火) 10:29:34
http://www.open-std.org/jtc1/sc22/wg21/
News 2006-11-06: C++ Standard Core Language Issues List (Revision 44) is available
02612442006/11/07(火) 15:23:23
下記のコードでfunc2()の引数objが初期化される時に
ユーザ定義コピーコンストラクタありだと
 c obj = c() ;
ユーザ定義コピーコンストラクタなしだと
 c tmp = c() ; c obj = c ;
となるみたいです。

DEBUG版だから最適化無効になっているはずなんですけどね。
コンパイラの最適化の話ではなく、C++の言語仕様なんだろうか。
--
struct c
{
c(){ cout << "c ctor" << endl ; }
//c( const c &obj ){cout << "c copy ctor" << endl ;}
~c(){ cout << "c dtor" << endl ;}
} ;

void func2( c obj ) {cout << "func2" << endl ; }

で、以下をユーザ定義コピーコンストラクタあり/なしで実行すると、
func2( c() ) ;

ユーザ定義コピーコンストラクタあり
c ctor
func2
c dtor

ユーザ定義コピーコンストラクタあり
c ctor
func2
c dtor
c dtor
0262デフォルトの名無しさん2006/11/07(火) 16:08:46
実行結果をノートパッドなどに出力する方法教えてください・・・
02632622006/11/07(火) 16:09:18
スレ違いでしたすいません
0264デフォルトの名無しさん2006/11/07(火) 16:13:26
動的な型決定みたいなことをしたいのですが、どこかに適当なサンプルコードなどないでしょうか

template< Any>//??
Any detAnyFromIndex(int index)
{
if(index==0)
return( (char)(... ) )
if(index==1)
return( (int)(... ) )
if(index==2)
return( (double)(... ) )
}
0265デフォルトの名無しさん2006/11/07(火) 16:45:52
>>264
templateをなんだと思ってるんだ?

最近template関係の質問多くなったな
それもアホみたいなのが。
流行ってんの?
02662642006/11/07(火) 17:04:54
templateでなくてもいいのだけど
関数の返す方を動的に変えたい
boost::any detAnyFromIndex(int index)
だと、データを取り出すときに結局
boost::any_cast<float>(output )
が必要になって処理が後回しにされるだけで解決にならない
0267デフォルトの名無しさん2006/11/07(火) 17:14:17
無理
0268デフォルトの名無しさん2006/11/07(火) 17:32:39
>>266
型は静的なものだから、動的に取得することは出来ません。
0269デフォルトの名無しさん2006/11/07(火) 17:39:08
できるもん!
0270デフォルトの名無しさん2006/11/07(火) 17:55:02
ドラえもん!
0271デフォルトの名無しさん2006/11/07(火) 17:55:20
>>266
その自身たっぷりんりんの発言はどこから来るんだ?
さっさとしね
0272デフォルトの名無しさん2006/11/07(火) 18:00:22
>>266
やりたいことを明確に汁
0273デフォルトの名無しさん2006/11/07(火) 18:06:21
>>264>>266
できません。
02742642006/11/07(火) 18:06:45
>>271
なぜに自身たっぷり?
よくわからないけど、プリプロセッサでなんとかできないか試してみる
0275デフォルトの名無しさん2006/11/07(火) 18:10:10
>>274
できません。
0276デフォルトの名無しさん2006/11/07(火) 18:13:04
>>274
できないっつってんだろうがボケww
プリプロセッサとか・・w
もう一度template勉強しろ
02772642006/11/07(火) 18:14:27
自己解決
boostのHPにあったサンプルで解決できそうです

#define ARITHMETIC_TYPE(I) ARITHMETIC_TYPE ## I

#define ARITHMETIC_TYPE0 bool
#define ARITHMETIC_TYPE1 char
#define ARITHMETIC_TYPE2 signed char
#define ARITHMETIC_TYPE3 unsigned char
#define ARITHMETIC_TYPE4 short
#define ARITHMETIC_TYPE5 unsigned short
#define ARITHMETIC_TYPE6 int
#define ARITHMETIC_TYPE7 unsigned int
#define ARITHMETIC_TYPE8 long
#define ARITHMETIC_TYPE9 unsigned long
#define ARITHMETIC_TYPE10 float
#define ARITHMETIC_TYPE11 double
#define ARITHMETIC_TYPE12 long double
0278デフォルトの名無しさん2006/11/07(火) 18:16:05
>>277
できません。
0279デフォルトの名無しさん2006/11/07(火) 18:16:25
「 t e m p l a t e 」で、「 動 的 な 型 決 定 み た い な こ と 」をしたいのですが、できません><
boost使っても出来ません><;;;;
どうすればできますか???
プリプロセッサ使えばできるんですか><
0280デフォルトの名無しさん2006/11/07(火) 18:17:11
本人が満足してんだからほっとけ。
やりたいことは分かったしそれが最適だと思うなら勝手にしろ
02812642006/11/07(火) 18:17:37
>>278
バカの一つ覚えみたいにうるせーよ
できねーってゆうならその証拠みせろ
0282デフォルトの名無しさん2006/11/07(火) 18:19:24
>>281
マクロはコンパイル時に展開されますから、動的な処理は行えません。
相談室で相談に対して正解教えてるのにその口ぶり・・・酷ス
0283デフォルトの名無しさん2006/11/07(火) 18:23:35
自分で Variant 型でも作ってみたら?
0284デフォルトの名無しさん2006/11/07(火) 18:23:55
ふむ。。。
具体的な例がでてないから、やきもきするのはわかるが、
その態度は気にくわんな
学生さん?
02852642006/11/07(火) 18:27:11
>>282
確かにできませんでした。
あきらめます。
0286デフォルトの名無しさん2006/11/07(火) 18:28:42
出来ないことの具体例ってのは難しいな。
0287デフォルトの名無しさん2006/11/07(火) 19:13:33
union
0288デフォルトの名無しさん2006/11/07(火) 19:23:51
C++かWinAPIかちょっと判断できなかったんでこちらで質問させてください
リソース管理クラスの目的で関数ポインタをメンバにしようとしてるんですが、
呼び出し規約が違うと関数ポインタに代入できないようで困ってます。
(今は各規約のポインタとコンストラクタを持ってる)
呼び出し規約ってのはtemplateで決定できないんでしょうか?

#include <windows.h>
template <typename T, typename R = void>
class AutoResource {
T resource;
R (/*WINAPIV*/WINAPI *killFunc)(T);
//  ↑ここをtempleateに
public:
AutoResource(T res, R (/*WINAPIV*/WINAPI *func)(T) ) : resource(res), killFunc(func) {}
~AutoResource() { (this->killFunc)(this->resource); }
};

void f(HMODULE h) { FreeLibrary(h); }
int main() {
AutoResource<HMODULE, BOOL> res(LoadLibrary(TEXT("freetype.dll")), FreeLibrary);
//AutoResource<HMODULE> ress(LoadLibrary(TEXT("shell32.dll")), f);
return 0;
}

コンパイラはVC8です
0289デフォルトの名無しさん2006/11/07(火) 19:48:09
>>288

template< typename T, typename R > struct killer_base
 : public std::unary_function< T, R > {
 virtual ~killer_base() {};
 virtual R operator()( T ) = 0;
};
template< typename F, typename T, typename R > struct killer
 : public killer_base<T,R> {
 F f;
 killer( F func ) : f(func) {}
 R operator()( T t ) { return f(t); }
};
template <typename T, typename R = void>
class AutoResource {
T resource;
auto_ptr< killer_base<T,R> > const killFunc; // noncopyable
public:
template< typename KillerFunc >
AutoResource(T res, KillerFunc func )
 : resource(res), killFunc(new killer<KillerFunc,T,R>(func)) {}
~AutoResource() { (*killFunc)(resource); }
};
0290デフォルトの名無しさん2006/11/07(火) 19:49:37
>>288
boost::function
0291デフォルトの名無しさん2006/11/07(火) 20:03:57
よこからすまん。
>>289のkiller_baseって何で必要なの?
0292デフォルトの名無しさん2006/11/07(火) 20:22:53
AutoResourceのコンストラクタの時点で関数の型が決定するから
0293デフォルトの名無しさん2006/11/07(火) 20:28:46
>>291
boost::shared_ptr の sp_counted_base と、sp_counted_impl みたいなもの。
コンストラクタ呼び出しで渡された型を保存しておくための方法。

0294デフォルトの名無しさん2006/11/07(火) 20:41:12
>>289
(゚д゚)スゲー とりあえず意図したとおりのものになりました
ありがとうございます



内容はまだ理解できてないけどな! 
0295デフォルトの名無しさん2006/11/07(火) 21:19:13
>>271
人格障害の診断をうけたほうがいいぞ
0296デフォルトの名無しさん2006/11/07(火) 22:19:59
>>292>>293

すまん。
まったくわからん。
0297デフォルトの名無しさん2006/11/07(火) 22:46:18
>>296
ああすることによって、killer<F, T, R>型(のうち具体的にはF)がなんであっても
統一的に基底クラスであるkiller_base<T, R>型のオブジェクトとして取り扱えるようになる。

boost::functionなんかも同じようなことをやっている。
0298デフォルトの名無しさん2006/11/07(火) 23:01:36
あああああああああああOK
理解した。ありがつ。
0299デフォルトの名無しさん2006/11/07(火) 23:47:53
#include "stdafx.h"
#include <limits.h>

int _tmain(int argc, _TCHAR* argv[])
{
int n,max=INT_MIN,min=INT_MAX;
bool flag=true;
do{
printf("整数を入力してください。");
scanf_s("%d",&n);
if(n==0) flag=false;
if(n>max) max=n;
else if(n<min) min=n;
}while(flag);
printf_s("\n最大は%d 最小は%dです。\n",max,min);

return 0;
}


VC++ Proでこれを実行すると0を入力したとき
コマンドプロント閉じちゃうんですがどうしたらいいんですか
03002992006/11/07(火) 23:51:01
あ、できました。
0301デフォルトの名無しさん2006/11/07(火) 23:54:46
ああ、答えをいただいて3時間超、ようやく判った。
ありがとう、おめでとう。
0302デフォルトの名無しさん2006/11/08(水) 00:03:32
ところでOperator()って何のためにあるの?
意味不明。関数ポインタでいいじゃん
0303デフォルトの名無しさん2006/11/08(水) 00:24:23
ステートを持たせることができる
0304デフォルトの名無しさん2006/11/08(水) 00:25:31
そんなもん構造体引数に渡せばいいだろ
0305デフォルトの名無しさん2006/11/08(水) 00:31:13
for_eachアルゴリズムの第三引数とか。
だんだんチラシの裏っぽくなってきた。
0306デフォルトの名無しさん2006/11/08(水) 00:34:19
>>302
D&Eには、理由がない限りどの演算子も多重定義できるようにしたというようなことが書いてある。
そもそも導入された理由はその流れだろう。

>>304
Windows APIのコールバック関数ではそういう風になっているな。
だが、operator ()を使って(というよりboost::bindなんかで束縛してやって)のほうが、スマートだと俺は思う。
STLを考えた偉い人もたぶんそんなことを考えたのだろう。
0307デフォルトの名無しさん2006/11/08(水) 00:35:19
型で管理できる。
0308デフォルトの名無しさん2006/11/08(水) 00:37:45
templateで渡せる。
0309デフォルトの名無しさん2006/11/08(水) 00:40:02
>>308
tmplateでどうやって渡すの?
サンプル教えて
0310デフォルトの名無しさん2006/11/08(水) 00:50:37
template<typename FUNC>
void call_funcobj(FUNC f)
{
f("hello,world") ;
}

void func(std::string const & message)
{ std::cout << message << std::endl ; } ;


class FuncObj
{
std::string header_ ;
public :
FuncObj(std::string const & header) : header_(header) { }
void operator() (std::string const & message)
{ std::cout << header_ << message << std::endl ; }

} ;

int main()
{
call_funcobj(func) ;
FuncObj f1("message : "), f2("メッセージ:") ;
call_funcobj(f1) ;
call_funcobj(f2) ;
}
0311デフォルトの名無しさん2006/11/08(水) 01:07:07
メンバ関数を呼び出させることができるのも便利だと思っている。
class Window
{
    // ...
public:
    void SetTitle(const std::string&);
    // ...
};

void f()
{
    Window w;
    call_funcobj(boost::bind(&Window::SetTitle, w, _1));
}
0312デフォルトの名無しさん2006/11/08(水) 02:59:48
http://www.open-std.org/jtc1/sc22/wg21/
News 2006-11-07: The 2006-09 mailing is available

Working Draft の新しい奴 n2134.pdf がうpされてる。
0313デフォルトの名無しさん2006/11/08(水) 03:45:37
どなたか ↓ のコードを utf8 化する方法を教えてください。

ttp://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/kasumi/kasumi2/
0314デフォルトの名無しさん2006/11/08(水) 05:02:17
>>313
つ[iconv]
0315デフォルトの名無しさん2006/11/08(水) 13:40:34
>>302
関数ポインタより効率がよくなるから
0316デフォルトの名無しさん2006/11/08(水) 18:59:29
ポインターからtypedefするにはどうすればいいのか
どなたかお教えいただけないでしょうか

struct sttest
{
typedef int myint;
};
typedef sttest * psttest;
typedef psttest->myint mymyint;
こんな感じのtypedefをしたいのですが構文エラーe2143などとなって
コンパイルできません
0317デフォルトの名無しさん2006/11/08(水) 19:11:52
>>316
何がしたいんだ?
typedefは型を定義するものだよ
0318デフォルトの名無しさん2006/11/08(水) 19:16:24
typedef sttest::myint mymyint;
こういうことがやりたいのかな?
03193162006/11/08(水) 19:16:52
したいことは

psttestしか受け取れないclassの中でstruct sttest で定義した
ypedefの情報をうけとりたいのです

template<typename Ptr = psttest>
class MyClass
{
typedef Ptr::myint mymyint;
};
0320デフォルトの名無しさん2006/11/08(水) 19:17:22
ESP の訓練をかねて >>316 の思考を読んだ結果

typedef sttest::myint mymyint

がしたいんじゃないかと感じた。
03213162006/11/08(水) 19:32:45
ポインターを渡すようにクラスMyClass を設計してしまったため
ポインターが持ってるtypedefの情報を渡すことができなくなって
しまったので、なんとか解決したい。というのがやりたいことです。
0322デフォルトの名無しさん2006/11/08(水) 19:38:51
>>321
ポインタがtypedefの情報もってるって…何か壮大に勘違いしてないか?
0323デフォルトの名無しさん2006/11/08(水) 19:49:41
>>316がしたい事は別の構文で書くと、

typedef a+b c と同じような事だと思った。
0324デフォルトの名無しさん2006/11/08(水) 20:02:22
template<typename T> struct RemovePointer
{ typedef typename T::myint type; };

template<typename T> struct RemovePointer<T*>
{ typedef typename T::myint type; };

typedef RemovePointer<psttest>::type mymyint;
0325デフォルトの名無しさん2006/11/08(水) 20:08:53
なるほど、ポインタ型で特殊化するわけか・・・
03263162006/11/08(水) 20:11:52
>>324
できました
感謝
0327デフォルトの名無しさん2006/11/08(水) 20:53:06
vector<vector<double>* > v;

vectorに値を格納していって、

for(int i = 0; i < n; i++){
for(int j = 0; j < x; j++)
cout << (*v[i])[j] << endl;
}
で表示するんですけど、

(*v[i])[j] ってどういう意味なんでしょうか?
不勉強で申し訳ないのですが、ご教授をお願いできないでしょうか?
0328デフォルトの名無しさん2006/11/08(水) 20:56:19
>>327
v の i 番目 (0から数える。以下も同様) に入っているポインタが指す先にある
vector<double>型のインスタンスの、j番目の要素への参照。
0329デフォルトの名無しさん2006/11/08(水) 20:57:57
>>327
おかしくないか?
*v[i][j]だと思うが。
0330デフォルトの名無しさん2006/11/08(水) 20:59:54
すまん
vector<double*>と勘違いしてた。
0331デフォルトの名無しさん2006/11/08(水) 21:02:34
>>328
ありがとうございます!
助かりました!

>>329
参考書をそのまま写したんですが、
おっしゃる通りにやってみたところ、
エラーになりました。
■ このスレッドは過去ログ倉庫に格納されています