【C++】template 統合スレ -- STL/Boost/Loki, etc.
>>951 boost::lexical_castは内部的にstd::stringstreamを使っている。
バラして書けばこんな感じ。簡単だろ。
int main()
{
std::string str("123");
std::stringstream sstr(str);
int i;
sstr >> i;
std::cout << i << std::endl;
}
>>952 す、素敵すぎです!ありがとうございました。
移行はするとしても、当座はこれでしのいでみます。
>>953 ちなみにstd::stringstreamのコンストラクタを起動した直後は書き込み位置
も読み込み位置もゼロになっているようだから、適当にシークして追加する
と良い。本当はstd::ios::pos_typeをstd::coutに出力できない場合もあるんだ
けどね。あくまでも例って事で。
int main()
{
std::string str("123");
std::stringstream sstr(str);
int i, j;
std::ios::pos_type p;
p = sstr.tellg();
std::cout << "read pos = " << p << std::endl;
p = sstr.tellp();
std::cout << "write pos = " << p << std::endl;
sstr.seekp(0, std::ios::end);
sstr << " 456";
sstr.seekg(0, std::ios::beg);
sstr >> i >> j;
std::cout << i << ' ' << j << std::endl;
}
sstr.seekg(0, std::ios::beg);
はいらなかったかな。
C++のストリームはCとは違って読み込みと書き込みのポインタは
別々だからね。
>>954-955 いやはや、コードは言葉より雄弁と言いますか・・・。
分かりやすくて本当にためになりました。ありがとうございました。
読んで置いて良かった・・・正直いうと、こんな使いかたしてましたよ(笑
int main()
{
int i;
std::string str("123");
std::stringstream( str ) >> i;
std::cout << i << std::endl;
}
>>945 #include <vector>
template<typename T>
struct foo {
static void Hoge(const T& t)
{
*****
}
static void Hoge(const std::vector<T>& t)
{
****
}
};
foo<int>::Hoge(0);
foo<int>::Hoge(std::vector<int>());
とかじゃダメなの?
>>945 やっぱ上のじゃ不便だな、ってことで以下...
template <int N> struct foo {
template <class T> static void baka(const T& t) { //hogehoge }
};
template <> struct foo<1> {
template <class T> static void baka(const std::vector<T>& t) { //hogehoge }
};
template <class T> char hage(const std::vector<T>& t);
double hage(...);
template<typename T>
static void Hoge(const T& t) { foo<sizeof(hage(t))>::baka(t); }
void test() {
int a = 3;
std::vector<int> v(8);
Hoge(a);
Hoge(v);
}
ちゃんとディスパッチできたよ。
sizeof(char) < sizeof(double) だと規格のどこに書いてあるのか小一時間(略
>>956 うぉ、こんなやり方でもできるんだな
やっぱ使うのまずいっぽ?
コンストラクタで作ってから、どうなってるんだろ
デバッガで追ってみたけどテンプレートが複雑でいまいちわからん
960 :
デフォルトの名無しさん:03/03/15 03:43
>>945 ふつうにオーバーロードで
template<typename T>
void Fn(const T&){}
template<typename T>
void Fn(const std::vector<T>&){}
int main(){
Fn(int() );
Fn<int>(std::vector<int>() );//Fn<int> 明示的に型指定
return 0;
}
>>956 の示したコードの使い方、あれでいいんじゃないですか?
あってるよね?
>>960 なるほど<int>と限定した上ではただのオーバーロードに
なるんだね。
複雑にして損したよ
>>959 >>961 自分で書いて置いてなんですが、あってるんですか?
さすがに無理な気がしないでもないです…要するにこういう事ですよね?
#include <iostream>
class B{
public:
void hage(){
std::cout << "Hoge" << std::endl;
}
};
int main(){
B().hage();
return 0;
}
実体はどこに・・・というかうちのコンパイラ(VC++6.0)以外でも通るのだろうか。
詳しい方のご意見をお尋ねしたいところです。ってC++スレの方がいいのかな。
>>963 ん?一時オブジェクトの寿命の問題でしょ
全然問題ないよ
>>964 いやぁ、そうなんですか・・・また一つ勉強になりました。
てっきり、Bコンストラクタのスコープから出た瞬間、
デストラクタが呼ばれるのかと思ってました。
Bコンストラクタ>hage>Bデストラクタは保証されているんですねぇ。
うーん、ダメだ。自分この辺ぐだぐだで・・・再勉強してきます。
レスありがとうございました。
一時オブジェクトってのは非constな参照では受けられないけど
非constなメソッドを呼べるという特殊な存在。
この性質を利用したテクニックもある。
でもこれを多用すると一部の論者に睨まれるという諸刃の剣。
一時オブジェクトって、非constな参照で受けられなかったんだ……。
言われてみると、敢えて受けてみたことはないな。
thx.
>>966 おまけに自分自身を返すメソッドを呼ぶと
非constな参照で受けることが可能になるだけでなく
当然左辺値として扱うことも可能になる。
一時オブジェクトは非constな参照で受けることが
できない/右辺値として扱われるって
仕様はホントにあほらしいんだよなぁ。
そんなんだったら始めからエラーじゃなくて、
ワーニング程度に留めとけっての。
>>960 intと明示的に型指定できるくらいだったらvectorなのか
そうでないのかもわかるだろうから、オーバーロードすら
必要ないんじゃない?
970 :
デフォルトの名無しさん:03/03/16 16:46
>>969 >>945 を、よめ!!!!!!!!!
ちなみにほかのコンパイラーなら
明示的の指定はいらん
971 :
デフォルトの名無しさん:03/03/16 16:49
>>963 そういう使い方ならstatic関数にすればいいやん
B::hage(); みたいに
>>970 945の意味するところが『いずれテンパラはある一つの型に決めます』ってなら
<T>の部分を明示するのは抵抗ないだろうけどね。
テンパラになる型が最終的に複数出てくる場合はどうだろう。
と思って957→958という流れになったわけだが
973 :
デフォルトの名無しさん:03/03/16 17:25
staticにしたらこんなのが通らん
#include<cstdio>
//#define STATIC__
struct FuncOperator
{
#ifdef STATIC__
static void operator () (){ puts("static operator"); }
#else
void operator () (){ puts("Non static operator"); }
#endif
};
int main(){
#ifdef STATIC__
FuncOperator::operator ()();
#else
FuncOperator()();
#endif
return 0;
}
staticなオペレータって蟻なのか?
>>958さん、ありがとうございます。たしかにうまくいきますね。
で、えぇと……実はHoge()はあるクラスのメンバ関数なんですが、
この場合はどうしたらいいんでしょう?^^;
条件が後出しになって申し訳ありません。詳しく状況を言いますね。
まず、バイナリの入出力を簡便にしてくれるクラスが欲しいのです。
標準だと、こうなりますよね。
ifstream ifs("piyo.dat",ios::binary);
int n;
ifs.read(reinterpret_cast<char*>(&n),sizeof(int));
vector<int> v(n);
ifs.read(reinterpret_cast<char*>(&v[0]),sizeof(int)*n);
これだとあまりにも面倒なのです。不要な指定が多すぎて。
CReadFile rf("piyo.dat");
int n;
rf >> n;
vector<int> v(n);
rf >> v
こういう感じですっきり指定できるラッパークラスを作りたいのです。
出力の方も、同じ要領でやりたいと思ってます。
これで、intだけを入出力したいわけじゃないから、templateで、
ということなんです。
で、VC6固有の(ですよね?)templateヘタレ解析に悩まされてるわけです。
そういうわけですので、
>>960さんみたいなやり方は、クラス使用者の
負担になりますので、あんまり意味がないわけです。
>>958さんのやり方みたく、多少機種依存の部分があっても、なんとか
隠蔽できればいいんですけど……。
して、次スレの方は?
>>976 template <class T> void hoge(const T &);
を用意しなければいいのでは
つまり
void hoge(int);//unsigned int,float,なども用意する
template <class T> void hoge(const vector<T> &);
でどうでしょう? あんまり無条件でバイナリ保存できる型なんてそうそうないでしょ?
逆に安全性の面から用意されていないと入出力できないようにしたほうが良いとおもわれ
979 :
デフォルトの名無しさん:03/03/17 17:42
reinterpret_cast<?>(?)のなにがいやぁーなの
もしながくていやとかぬかしてんのそれなら(char*)キャスト使えば
もし、それでもかっこ悪いとか言うんなら自分でvector<T>専用をつくれば
template<typename T>char* Cast(std::vector<T>& tt)
{return reinterpret_cast<char*>(&tt[0]); }
こんな感じに。
さらにintとunsigned charを使い分けたいなんて我侭もあるんなら
union bit{
int i;
unsigned char bitn[4];
};
std::vector<bit>これで読み込ませればint、
unsigned charの使い分けが一回の作業で実現できよう。
とにかくreinterpret_castぐらいでクラスなんて作ってられない
#define scast static_cast
#define rcast reinterpret_cast
#define ccast const_cast
#define dcast dynamic_cast
template <class T,class U> T scast(const U &u)
{ return static_cast<T>(u); }
982 :
デフォルトの名無しさん:03/03/17 21:14
>>980 それをやるならここでは、こうでしょ。。
#define Cast(M) reinterpret_cast<char*>(M)
983 :
デフォルトの名無しさん:03/03/17 21:19
>>981 いみない。結局明示的に指定しなくちゃならんでしょ
>>982 char * 型以外に使えないじゃん。
ねえ、早く!
template<typename STL,Boost,Loki,etc>class part2
〈〉←これで代用という手がある。
991 :
デフォルトの名無しさん:03/03/19 20:53
777?
992 :
デフォルトの名無しさん:03/03/19 22:52
この板では1000ゲットは興味なしですか?
ぬるぽがこのスレに興味を持ったようです。
∧_∧
( ´∀`)< ぬるぽ
∧_∧
( ´∀`)< ぼくぬるぽ
もうすぐか…
なにが?
999
そんなバカなやり取りしてる間に1000げt
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。