【C++】template 統合スレ -- STL/Boost/Loki, etc.
1 :
デフォルトの名無しさん :
02/11/20 21:29
重複スレで良いな?
boost固有の話は boostスレでやってくれていいけど、いずれは このスレに統合するってことで。
C++標準以外のものは使うな。よってSTLのみとする。
スレ立ったの見て一瞬 (゚Д゚)ハァ? と思ったが、後で合流するならいいか。
カレー
乙 マターリ逝きましょう
12 :
デフォルトの名無しさん :02/11/21 01:04
#include <memory> class B {}; class D : public B {}; std::auto_ptr<B> f() {   std::auto_ptr<D> p;   return p; } ↑の一見通りそうだけど、エラーになります。 test.cpp:9: no matching function for call to `std::auto_ptr<B>::auto_ptr( std::auto_ptr<B>)' /usr/include/c++/3.1.1/memory:346: candidates are: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = B] /usr/include/c++/3.1.1/memory:216: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = B, _Tp = B] /usr/include/c++/3.1.1/memory:203: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = B] test.cpp:9: initializing temporary from result of ` std::auto_ptr<_Tp>::operator std::auto_ptr<_Tp1>() [with _Tp1 = B, _Tp = D]' とりあえず、   return std::auto_ptr<B>( p ); で、エラーにならなくなるようです。 この修正が妥当なんでしょうか?
>>12 std::auto_ptrが継承に対応してないからかと思ったけど、どうも区別が
曖昧だというエラーが出るね。
なかなか難しいよね。templateベースのものは。 まあ仕事にも使った事はあったけど。便利なんだけど。
継承は対応してないのか。確かに通らんね。 #include <memory> class B {}; class D : public B {}; std::auto_ptr<B> f() { std::auto_ptr<D> p; return dynamic_cast<std::auto_ptr<B> >(p); }
auto_ptr<B>とauto_ptr<D>は単に別の型であって、
暗黙の型変換ができなかった、ということでは?
>>15 そこでdynamic_castを思い浮かべてしまうというのは
ちと知識不足すぎやしませんか。ネタ?
>>16 いや(汗、本当に継承に対応してないのかと思って。
でもパラメタの型が違うから当たり前か・・・・
>>16 ttp://www.kuzbass.ru/docs/isocpp/lib-utilities.html#lib.auto.ptr ↑には、
>template<class Y> auto_ptr(auto_ptr<Y>&) throw();
>Requires: Y* can be implicitly converted to X*.
>template<class Y> auto_ptr& operator=(auto_ptr<Y>& a) throw();
>Requires: Y* can be implicitly converted to X*. The expression delete get() is well formed.
っていうインターフェースがあるようで、
auto_ptrの規格は、
>>12 の最初のコードが
コンパイルできるように配慮されているように見えます。
同時に、余計な変換手段に見えるインターフェースもありますが・・・。
よく読み直してみろ
20 :
デフォルトの名無しさん :02/11/21 22:19
統合スレになったとたんレベルが...
C言語スレみたいにバカをネタにしてつきあうぐらいの寛大さが必要です
22 :
デフォルトの名無しさん :02/11/21 22:33
でも確かに、何でstd::auto_ptrにキャストオペレータ入れなかったんだろうとは思うね。
std::auto_ptrってどんなメンバ関数があるのだろう?
> std::auto_ptrにキャストオペレータ 作るとしたらどんなコーディングになる?
template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref) { return std::auto_ptr<T>( ref.release() ); } と、やりたいけど出来ないんだよな
そうじゃなくて、自分がauto_ptrの設計者だとしたら。
>>19 読み直してみたけど、新しく気づいたことはなかったです。
・・・やっぱりわからん。
<memory>を読んでみたけど、変換インターフェースの実装のところに、
「派生関係の変換が可能になるように、これらのモノが必要」みたいなコメントまで書いてある。
コメント中にあるサンプルと同様のコードをコンパイルしようとしたけど、
やっぱり
>>12 と同じエラーになる。
モッカイageテミル
>>25 release()必要ないのでは?std::auto_ptrのコンストラクタは所有権を
移動させるから。
auto_ptr<T>とauto_ptr<U>の互換性があるかどうか分からないのに、 どうやって所有権を移動させるんだ?
継承と同じように考えて、親クラスのポインタ変数に子のオブジェクトのアドレス を代入できるかと自然と考えてしまいました。でもstd::auto_ptrは継承とか考慮 してないので、エラーになるのですね。
>>12 むしろ継承関係にあるからこそのエラーと思われ。
継承関係になかったら別のエラーになるけどさ。
gcc-2.95.3 でcompileしてみた。
conversion from `auto_ptr<D>' to `auto_ptr<B>' is ambiguous
: candidates are: auto_ptr<D>::operator auto_ptr<B><B>()
: auto_ptr<B>::auto_ptr<D>(auto_ptr<D> &)
>>29 互換性があればcompileできるだろ?
あぁ
>>25 のままじゃcompileできんな
template<class T, class U>
std::auto_ptr<T> cast(std::auto_ptr<U>& ref, std::auto_ptr<T>&)
{ return std::auto_ptr<T>( ref.release() ); }
だね。
つーか、むしろ
template<typename T, typename U>
T cast(U &ref, T &) {return T(ref.release());}
33 :
デフォルトの名無しさん :02/11/22 03:52
>>32 そのテンプレート関数はどうやって呼び出すんだ?
template<typename Y> std::auto_ptr<X>::auto_ptr( std::auto_ptr<Y>& r );
template<typename Y> std::auto_ptr<X>& std::auto_ptr<X>::operator = ( std::auto_ptr<Y>& r );
template<typename Y> std::auto_ptr<X>::operator auto_ptr<Y>();
↑キャストなんて標準で装備されてるこれらで十分のはずだ。
>>34 >そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
2!
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
え
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。
>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、
>>31 の内容は理解できましたか?
>>31 通常時、TとUには互換性があるかも知れないが、
auto_ptr<T>とauto_ptr<U>に互換性があるときはT==Uの時だけだろ。
一体このスレは何が起きているんだ?
>>42 もう後には引き下がれない意地と意地のぶつかり合いが
繰り広げられています。
異常なほど向きになっておりますな。 しかも会話がかみ合っていないときている。
意見が噛み合ってないのは議論じゃなくて論破しようとしてるせい。
ん? とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか?
>>31 器用な人ですな。
> で、
>>31 の内容は理解できましたか?
え・・・?理解できません、たぶん。
あと、キャストする関数の引数が二つなのが理解できませんねぃ。
> ん? > とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか? (゚Д゚)ハァ?
> > ん? > > とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか? > > (゚Д゚)ハァ? (゚Д゚)ハァ?
50 :
デフォルトの名無しさん :02/11/22 20:59
時期ヴァージョンのJava(J2SE1.5)でJavaGenerics(?)がコアAPIに統合されテンプレートが使えるようになり、コレクション系インターフェースの問題が 解消されるというのでちょっと期待しているのですが C++でテンプレートを使うメリット、デメリットとはどんなものでしょうか? 投稿記事のC++ソースを見た感じ、複雑そうに見えます。 テンプレートを使いこなすには修行が必要そうですね。
STL ライクなコードが Java で書けるというだけで、template が使える というのとは違うと思っていたが気のせいか?
>>37-40 すげぇ、これこそまさにテンプレートなんだね。感心。
>>41 > auto_ptr<T>とauto_ptr<U>に互換性があるときはT==Uの時だけだろ。
いや。
>>18 とか
>>34 にも書いてある。
それを、互換性がある、と言わないとか、
class B {}; class D : public B {}; のときは B == D というなら
そういうもんなのねとあきらめる。
>>47 > あと、キャストする関数の引数が二つなのが理解できませんねぃ。
#include <memory>
template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref)
{ return std::auto_ptr<T>( ref.release() ); }
template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref, std::auto_ptr<T>&)
{ return std::auto_ptr<T>( ref.release() ); }
class B {};
class D : public B {};
main() {
std::auto_ptr<B> b;
std::auto_ptr<D> d;
b = cast(d, b);
b = cast<B>(d);
}
でどうよ。
これは通るけどこれでもいいの? template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref) { return std::auto_ptr<T>(std::auto_ptr<U>(ref)); }
>>55 読んでみました。この通りです。
class A {
public:
int i;
};
class B : public A {
public:
int j;
B(int x, int y) { i = x; j = y; }
};
template<class T, class U> std::auto_ptr<T>
inline cast(std::auto_ptr<U>& ref)
{
return std::auto_ptr<T>(std::auto_ptr<U>(ref));
}
int main()
{
std::auto_ptr<B> ptr(new B(123, 456));
std::auto_ptr<A> pa;
pa = cast<A>(ptr);
std::cout << pa->i << std::endl;
ptr = cast<B>(pa); // ダウンキャストはだめ?
std::cout << ptr->j << std::endl;
}
で、 pa = cast<A>(ptr); は通るんですが、 ptr = cast<B>(pa); // ダウンキャストはだめ? はだめなんです。もっとも、この行はrelease()を使った版でも 通りませんでした。
>>56-57 何、通るの!?
げ、STLportだと通るよ。
> ダウンキャストはだめ?
reinterpret_castしてるわけじゃなくて
pointerのoperator=だからねぇ。
>>58 gcc3.2でも通るよ。
>reinterpret_castしてるわけじゃなくて
>pointerのoperator=だからねぇ。
あっそうですね。考えてみればそうだ。
>>12 の話に戻るけどさ、
auto_ptr<B> p = auto_ptr<D>(); // (1)
p = auto_ptr<D>(); // (2)
g++ 3.1 で (1) が通らないんだけど、
誰か解説してくれ
>>60 auto_ptr<型>()はコピーコンストラクタだからじゃない?
>>60 スマソ。std::auto_ptr(T* p = 0) はコンストラクタだね。
ところで
std::auto_ptr<B> p = std::auto_ptr<B>(std::auto_ptr<D>());
は通るよ。
んー、ということは、std::auto_ptrの代入演算子とコピーコンストラクタの 書き方に対称性がないということになるね。
あとね auto_ptr<D> d; auto_ptr<B> b0(d); // OK auto_ptr<B> b1 = d; // NG なのよ。 auto_ptr<B> b2(auto_ptr<D>()); はfunction declarationになっちゃうからいいんだけど。
>>64 それは、std::auto_ptrのコンストラクタがexplicit宣言されている事と
関係があると思う。
つまり、 auto_ptr<B> b0(d); // OK の時はコンストラクタを呼び出してくれるけど、 auto_ptr<B> b1 = d; // NG の時はコピーコンストラクタが呼び出されてしまい、それが buggyなのでエラーになるかと。違うかもしれんけど。
いろいろ調べてみたら、std::auto_ptrには template class<T> operator std::auto_ptr<T>() という変換演算子があるらしい。この格好がコピーコンストラクタと 酷似しているため、コンパイラが混乱してしまうようだ。 だから明示的にコピーコンストラクタを呼び出してやればいいと思う。
最初の #include <memory> class B {}; class D : public B {}; std::auto_ptr<B> f() { std::auto_ptr<D> p; return p; } に戻ってみると、return p; の時点で、 std::auto_ptr<D>をstd::auto_ptr<B>にコピーするコピーコンストラクタを 呼び出すか、std::auto_ptr<D>をstd::auto_ptr<B>に変換する変換演算子 を呼び出すか曖昧だからエラーが出たようだ。
そうすると、 return std::auto_ptr<B>(p);は、コピーコンストラクタなのか、それとも 変換演算子なのか?誰か教えてください。
さらに深く調べると、 return std::auto_ptr<B>(p); もエラーになるのは、これもコピーコンストラクタか 変換演算子なのか曖昧だという事がわかった。 エラーを回避するには、 std::auto_ptr<B> f() { std::auto_ptr<D> p; return std::auto_ptr<B>(std::auto_ptr<D>(p)); } のように書かなければいけないようだ。この場合コンパイル出力をアセンブリ出力 で見てみると、コピーコンストラクタを呼び出した後変換演算子が呼び出されていた。
>>71 ちょっと違うかもしれないが、だいたいこれと同じような現象が起こって
いるようです。
class B;
class A {
public:
A() {}
A(B*) {}
A(B&) {}
};
class B {
public:
operator A() { return A(this); }
};
int main()
{
A a;
B b;
a = b;
}
関数も付け加えてみました。スレ違いにてここまで。 class B; class A { public: A() {} A(B*) {} A(B&) {} }; class B { public: operator A() { return A(this); } }; A f(B& b) { return b; } int main() { A a; B b; a = b; f(); }
あっ、f()でなくてf(b)です。
>>70 return std::auto_ptr<B>(p);
これはエラーにならずに通るぞ。
>>69 こういうのは、「変換コンストラクタ」とか言うんじゃないの?
ちなみに、 std::auto_ptr に「コピーコンストラクタ」は無いと言える、よね?
std::vector<std::string> str; と宣言して str.push_back(buf); (bufはchar型の文字列) という感じで値をつめていくと「識別子が '255' 文字に切り捨てられました」 とコンパイラの警告が出ます。char型の文字列をどんどん追加していきたいのですが、 正しい値の代入の仕方があれば教えてください。
>>76 それは文字列が切りつめられたんじゃなくて、
templateを展開した型の実名が長すぎるから切りつめられただけ
#pragma warning(disable:4503) #pragma warning(disable:4786) で黙らせる。
俺ら最強!YO!
82 :
デフォルトの名無しさん :02/11/24 11:40
auto_ptrは解決したようなので... 何度も出てる質問だと思うけど、boost仕事で使ってる? オレんところは小さい会社だし、仕事がR&D的だし、 わがままは通るから勝手に使っちゃってるけど。 templateやSTLでさえも使えない会社って多いんでしょ? (ならC++なんか使うなって感じだけどな。)
ここのスレの人はgcc使ってるの? 環境がwindowsだとmingw?
>>83 ワシはBCB6れす。boost::lambda使いたいよ〜。
cygwin-bccはまだ2.95だよね?
SDKのコンパイラも新しくなるのかな?
87 :
デフォルトの名無しさん :02/11/24 12:27
51>> C++のテンプレートそっくりなものをそのまま使えるわけでは無いようですが、これによりJavaの型キャストの問題に悩まされなくなり、instanceof修飾子を使わずに済むようになり、よりオブジェクト指向的なコードがかけるようです。
>>85 g++使って書いたコードって、VCでコンパイル通る?
俺はだめだ。template周りが弱すぎるよ、VCって。
そんなわけでVCはほとんど使えない。辛うじてBCBかな。
>>85 コンパイル済みオブジェクトが添付されるって、
exportがサポートされるってこと?それはすごい!!!
90 :
デフォルトの名無しさん :02/11/24 13:31
template <int M, int N=1>
class StaticArray{
public:
inline static const double* init(){
(N-1<M)?(StaticArray<M,1>::data[N-1]=double(N-1)):0;
StaticArray<M,N-1>::init();
return StaticArray<M,1>::data;
}
};
template <int M>
class StaticArray<M,1>{
static double data[];
public:
inline static void init(){ StaticArray<M,1>::data[0]=0;}
template <int,int>
friend class StaticArray;
};
template <int M>
double StaticArray<M,1>::data[M];
int main(){
const double* array=StaticArray<20,10>::init();
for(int i=0;i<20;i++) std::cout << " " << array[i];
std::cout << std::endl;
}
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html でいってたすたちっくに配列の初期化するのってこんなんだろか
>>88 さすがに export は無理じゃろ。
たんにregexとかのライブラリがコンパイル済みで提供される、
ってことだと思う。
>>91 Lambdaが使えるなら、それでもいいかも。
>>91 いや、そうでもないんじゃない?
C# にジェネリクス実装するのなら、結局 C++ の export 相当の機構が必要になる。
MS 内部でどういう開発グループ分けになってるかは知らないけど、
彼らが知識共有していくとしたら…。
>>93 C#じゃなくてVC++でしょ(8.0だっけ?)
標準に98%準拠っていうあれでしょ。
でも今ので90%だって自称してるんだから期待できないけど。
>>94 おわかりですか?
export が VC++ に実装されるって話題です。
C# で同等の技術が必要になるから C++ でもやるんではないか?
という事です。
というか 98% の残りの 2% はいったい何なんだ。
98っていう数字がなんだか微妙だよね(藁
>>93 C#とJavaのGenericsは基底クラスがあるからなぁ。
C++でうまくいくのかなあ。
残り2%がtemplate周りだったらいやだなぁ。
うまくいくならVC8買っちゃうんだけど。
2ちゃん内に対するリンクを切るのは止めてくれ。
export とベースクラス Object/object がある事って関係ないんじゃ?
102 :
デフォルトの名無しさん :02/11/24 20:02
STLのmapについての質問なのですが、 「mapの要素の挿入と削除には対数時間(logN)が必要ですが、 位置を指定して要素を挿入する場合は償却定数時間(ε)しかかりません。」 と本にあったのですが、いまいちよく分かりません。 (1)削除 void erase(iterator i); -> logN ? void erase(iterator start,iterator end); -> length*logN ? size_type erase(const key_type &k); -> logN ? (2)挿入 iterator insert(iterator i,const value_type &val);-> ε ? template<class InIter> void insert(InIter start,InIter end ); -> length*logN ? pair<iterator,bool> insert(const value_type &val);-> logN ? であってますでしょうか?
「反復子で指定した要素の削除は定数時間です。」を忘れてました。
void erase(iterator i); -> ε に修正します。
>>103 [挿入|削除]する[位置|反復子]が分かっているときは定数時間だが、
その位置を探すのにlower_bound ->logN 時間かかるということですかね。
ありがとうございました。
105 :
デフォルトの名無しさん :02/11/26 19:20
type_of演算子作りたいんだけど。 コンパイラがどの型にも固有の値を割り振っていて、 それをコンパイル時に参照できたら 式templateとマクロでtype_of作れるんだけど、 静的使えるのがsizeofしかないぽいから無理くさいのかな。 //ないんでとりあえず実験 #define class_id(x) sizeof(x) template <int> struct Type_of; struct Type_of<class_id(int)>{typedef int type;}; struct Type_of<class_id(char)>{typedef int type;}; #define type_of(x) Type_of<class_id(a)>::type #include<iostream> int main() { int a; char c; type_of(a) a2=200; type_of(c) c2=100; std::cout << a2 << c2; }
修正: × struct Type_of<class_id(char)>{typedef int type;}; ○ struct Type_of<class_id(char)>{typedef char type;};
VC++7.0 限定でよければ…(C++の規格的には間違っているらしい) ----------------------------------------------- typedef char (&no_tag)[1], (&yes_tag)[2]; template<int> struct id_counter; template<typename> struct t2t; template<typename T> no_tag test(T*, ...); #define EMPTY(n) sizeof(test((t2t< id_counter<n> >*)0))==sizeof(no_tag) template<int val_ = (EMPTY(1) ? 1 : (EMPTY(2) ? 2 : (EMPTY(3) ? 3 : (EMPTY(4) ? 4 : (EMPTY(5) ? 5 : (EMPTY(6) ? 6 : (EMPTY(7) ? 7 : (EMPTY(8) ? 8 : (EMPTY(9) ? 9 : -1)))))))))> struct id_counter { enum { val = val_ }; friend yes_tag test( t2t< id_counter<val> >* ); }; template<typename T> struct id_of { enum { val = id_counter<>::val }; }; #define class_id(T) id_of< T >::val
#include <iostream> int main() { std::cout << class_id(int) << ' ' << class_id(int) << ' ' << class_id(char) << ' ' << class_id(int) << ' ' << class_id(long) << ' ' << class_id(std::istream) << std::endl; } が 1 1 2 1 3 4 になる。とゆーか、分割コンパイルまで考えると、コンパイラ的にはtypeofよりも staticなTypeIdの方がよっぽど面倒な気がするので、素直にc++0xを待つべきかと。
今思いついた。sizeofと同じく式に対しても使えるようにするには、こんな感じ。 template<typename T> struct sized { char size[id_of<T>::val]; }; template<typename T> sized<T> obj_class_id_helper(const T&); #define obj_class_id(x) sizeof(obj_class_id_helper(x).size) //int a; float b; //assert( obj_class_id(a+b) == class_id(float) );
>>107 すごすぎる!!!
id_counterってほんとにその名の通りですね。
少し手を加えて
type_ofとtestプログラム作ってみたけど、
こういうものはウプしてもいいのかな?(どういう場所がいいのか)
どうにか手を入れれば、GCCでも動かせそうな気がするんだけど、
自分では無理そうでした。
111 :
デフォルトの名無しさん :02/11/27 14:20
>>107 逆に、IDから元の型を取得することはできないの?
float f = 1f;
int i = (class_id(int))f;
キャストに使えたりするとうれしい。
jokeだろ
>113 しっ!!
うお!IPってデータリンク層に鳩使っても使用可能なんだってさ! RFC勉強になりすぎ。
ttp://www3.to/typeof にとりあえず上げてみました。
中を見ると分かるけど
>>111 int i = (type_of_id( class_id(int) ))f;
でできます。でもType_ofで登録した物にしか使えません。
>>107 ちょこっと追加として
int addfunc(int,int);
type_of_declare(addfunc(int,int),aa);
std::cout << aa;
とかできるようにした。(定義場所わかりにく...
>>107 (116)
入れ子の式テンプレートでできないかと思ったけど撃沈...。(以下、略
template <typename T> struct Type_of_collection
{
template <int N> struct Type_of_Num;
struct Type_of_Num<class_id(T)> { typedef T type;};
};
118 :
デフォルトの名無しさん :02/11/28 12:01
119 :
デフォルトの名無しさん :02/11/28 15:05
質問です。VC++6.0で #include <list> using namespace std; void main(){ list<list<int>> a: } というのでエラーがでます。 listのlistを作るにはどのようにしたらいいのでしょうか?
>>が引き篭もりなのです
>list<list<int>> a: 色々違ってるな。
122 :
デフォルトの名無しさん :02/11/28 15:11
>120 ありがとうございました。 直りました。
123 :
デフォルトの名無しさん :02/11/28 15:37
>C++ Compiler 7.0 for Windows \55,000
std::vectorのstd::sortが予想外に速い。インライン展開の賜物か。 const int N = 2000000; int cmp(const void *, const void *); int main() { static double d[N]; std::vector<double> vd; std::clock_t ti; std::srand(0); for (int i = 0; i < N; i++) d[i] = std::rand(); std::srand(0); for (int i = 0; i < N; i++) vd.push_back(std::rand()); ti = std::clock(); std::qsort(d, N, sizeof(double), cmp); std::cout << "qsort = " << std::clock() - ti << std::endl; ti = std::clock(); std::sort(vd.begin(), vd.end()); std::cout << "sort = " << std::clock() - ti << std::endl; }
int cmp(const void* a, const void* b) { if (*static_cast<const double*>(a) < *static_cast<const double*>(b)) return -1; else if (*static_cast<const double*>(a) > *static_cast<const double*>(b)) return 1; return 0; } qsort = 906 sort = 734
intだと qsort = 702 sort = 328 差が開く。
intでcmp()を int cmp(const void* a, const void* b) { return *static_cast<const TYPE*>(a) - *static_cast<const TYPE*>(b); } に換えたらちょっと速くできるけどまだsort()の方が速い。よくできてるなあ。 qsort = 562 sort = 344
あっごめん、環境はBorland-C++5.6.2(STLport装備)ね。
130 :
デフォルトの名無しさん :02/11/29 10:08
Win98SE、VC6SP5、PentiumIII-800。 STL は VC6 付属のもの。 コンパイラ付属のソースをインライン展開しまくった my_qsort でもやってみたよ。 double: my_qsort = 4340 qsort = 4720 sort = 1760 int: my_qsort = 1540 qsort = 3240 sort = 830 int (quick cmp): my_qsort = 1430 qsort = 2520 sort = 830 どうも、インライン展開うんぬんより、アルゴリズムが根本的に違ってるように見える。 STL のソートって何ソートなの?
sort って比較と入れ替えが処理のメインだから、そこが関数呼び出しになって しまって最適化されない qsort は正直かなりのオーバーヘッドがあると思う。
>>130 qsort の方はよく知らんが、STL の方は、
基本はクイックソート
pivot には先頭・ど真ん中・末尾の要素の中央値を使う
要素数が小さくなってきたら挿入ソートに切り替える
あと、最新版では再起が深くなってきたらマージソートに切り替えるって機能も付いてたと思われ。
標準のstd::logical_and、std::logical_orの使い方がよくわかりません。 参考書を読むと、標準にはないbinary_composeと組み合わせて使うと 書いてあるのですけど、どういう意味なのでしょうか?
>>131 130 の 3 行目は読んでくれたか?
> int (quick cmp):
> my_qsort = 1430
> sort = 830
その関数呼び出しのオーバーヘッドが無い状態で、これだけ差があるの。
>>132 VC6 付属の qsort.c については、
> pivot には先頭・ど真ん中・末尾の要素の中央値を使う
> 要素数が小さくなってきたら挿入ソートに切り替える
これと同じっぽい
要素数 8 以下で挿入ソートに入る。
ただし、マージソートはやってなくて、再帰は使わずに goto で戻してる。
ネックになりそうなのは、STL の場合のように代入演算子が使えないので、
char 単位にデータ転送しているところかな。
でも、それを無理矢理 int 決め打ちの swap にしても、まだ sort() のが
速い。
> my_qsort = 1100
後は何だ?
>>133 binary_composeにはSGIのSTLやSTLportで定義されている。std::compose2
というヘルパ関数を持つ。
例えば _1 < 1 || 3 <= _1 という関数オブジェクトを作るには
std::compose2(std::logical_or<bool>(), std::bind2nd(std::less<int>, 1), std::bind2nd(std::greater_equal<int>, 3))
とすればよい。
boostではネーミングが異なり、boost::compose_f_gx_hyとなっている。
> ネックになりそうなのは、STL の場合のように代入演算子が使えないので、 > char 単位にデータ転送しているところかな。 double が異様に遅いのはこのせいだな。 インライン展開しまくり、かつ代入演算子に変えたら、sort() に肉薄した。 my_qsort = 1965 qsort = 4715 sort = 1753 でもやっぱり sort() のが遅いけど。 あと、↓でより正確に測れる。 #pragma comment(lib , "winmm.lib") #define clock_t DWORD #define clock() timeGetTime()
> でもやっぱり sort() のが遅いけど。 sort() のが速いけど。ですた。
> boostではネーミングが異なり、boost::compose_f_gx_hyとなっている。 スマソ。boost::compose_f_gx_hxとなっている。に訂正します。
>>136 そうだったのか。あらゆる型に汎用にするために、charでアラインされた
転送単位を持つためにqsort()は遅いのか。
ということはcharでsortするとそんなに差は出ないはずだな。
・・・・やってみた。
qsort = 265
sort = 282
測定誤差により、逆転する事もあるが、大ざっぱに測定するとqsort()の
方が速くなった。納得。
STLとboostを一度同じ土俵に上げて、そのよさを比較し、 なし崩しにboostを認めようという作戦ですか? 私は認めませんよ!>boost
>>STL ごめんなさい
標準 boost → SB
次期STLは間違いなくboostからいくつかの機能を取り入れるだろうに。
template< class T, class U > U hoge( T foo, U* = NULL ) { ... } // 使い方 hoge<string, int>( "第二引数はダミー" );
よけーなオーバーヘッド食いそうだ
>>117 >
ttp://www3.to/typeof 素晴すぃ。
結局friendで勝手に定義を挿入するしかなさそう、と思ってその方向で
弄ってたんだけど、id_counter と違ってsizeof以上の情報を
オーバーロードされた関数からとってこなきゃいけないのがうまく行かなくて撃沈続き…。
template<class T, class U> U hoge(T foo, U* up = 0) { return *up; } int main() { hoge<std::string, int>( "第二引数はダミー" ); } としてみてもなあ。。。。intが無駄に使われているような気がして ならない。
>150 じゃなくて、ふつーに書くと返り値の型が異なるだけの関数は多重定義できん という話でしょ。 template じゃなくても良いんだが int foo(); void foo(); これは NG だが、 int foo(int); void foo(); これなら行ける。 > intが無駄に使われているような気がして とりあえず最適化有効にしてアセンブラ出力させてみ。
inline化されたら無駄な引数はなかったことになるだろうねえ
つまり、第二引数の型を変えて多重定義するためというものなのか? 今いち存在意義がわからんが・・・・・・
俺も今一分かってないんだが, int GetValue("キー") string GetValue("キー") みたいなことができるってことかい?
ごめん。なんか違うみたい・・・ 具体的な使用例をあげてみてくれないかい?
>>156 155 はそんなことをする理由を訊きたがっているんだぞ。
無理やり使いどころを考えると、template クラスで Factory 関数を使うときか?
>>157 そういうことです
(だから
>>154 でわざわざ”GetValue"という関数名を使ったのですが伝わらなかったようで・・・)
>無理やり使いどころを考えると、template クラスで Factory 関数を使うときか?
うーん。確かに無理やりですね。
Widget MakeWidget() ※Widgetは基底クラス
ってするもんじゃないでしょうか。
同じ関数名で返り値が違うってのがそもそも想像できないんですが・・・。
連カキすまん。 利用法が無いなら無いでいいんです。 「こういうこともできるよ」って例なのだとしたら。 でも実際に使いどころがあるんでしたら聞いてみたいのです。
>>151 それなら
template<class U, class T>
U hoge( T foo )
{
...
}
// 使い方
hoge<int>( "第二引数なんざ要らん" );
で十分では?古いヘタレコンパイラでどうなるかは知らんが。
>158 > 同じ関数名で返り値が違うってのがそもそも想像できないんですが・・・。 template を使って Mixin (あるいは Strategy パターン) をを書くときに使える。
>160 それだと、明示的に型を指定する必要があるのが難だなぁ。 パラメタとして関数オブジェクト、関数ポインタ、ともかく () つければ処理して くれるモノ何でも渡せるようにしておくと、コードの汎用性が上がる(場合がある)。
>>162 引数をtemplateにして型指定を緩くしとくと嬉しい、というのはその通りだけど、
この場合関係ないでしょ。(
>>144 のも同じく明示的な型指定が必要)
違うのは返値の型のみ、という関数を作りたいとき (例えばModern C++ Design の
Factoryパターンの話とか) の話でないの?
>>160 が通るコンパイラが有るなら教えてくれ。
>164 ないだろう。class を typename にすれば通るけど。
166 :
デフォルトの名無しさん :02/11/30 17:45
class_idだけど、テンプレートの特殊化のときにちょっとだけ違うためだけに 同じもの作らなくて済ませることができそうな気がする。 これって実行時に判定してるのかな? Tって静的だけどデバッガで見るとswitch文の中は最適化されてないみたいなんです。 template <typename T> struct FFF { FFF(T a=0) { switch( class_id(T) ) { case class_id(char): std::cout << "char" << std::endl;break; case class_id(short): std::cout << "short" << std::endl;break; default: std::cout << "other" << std::endl; } } }; template <> struct FFF<int> { FFF(int a=0) { std::cout << "int" << std::endl; } };
int main() { //出力結果 FFF<int> fff1; //int FFF<char> fff2; //char FFF<short> fff3; //short }
>>164 VC++.NET と Bcc5.51 と DigitalMarsC++8.31 と
g++3.2 と g++2.95 と Comeau C++4.31 と Intel C++6.0 では通ったが?
通らないコンパイラを教えてくれ。
169 :
デフォルトの名無しさん :02/11/30 20:21
うっひょっひょ( ゚∀゚ )
class_id(char) ->1 (enum定数) class_id(short) ->3 (enum定数) 直接は飛んでないけど、結局同じなんで問題ないか。 (↓最適化なしのものVC)最適化すると変わるんだろうか...。 ; 168 : FFF<char> fff2; mov DWORD PTR -416+[ebp], 1 cmp DWORD PTR -416+[ebp], 1 je SHORT $L23144 cmp DWORD PTR -416+[ebp], 3 je SHORT $L23145 jmp SHORT $L23146
>>21 ひどいことを言うなよ。お前だってアホだったろうが
ネタがないとスレが荒むな。
それもあるけど、昔と比べると荒れすぎ。
>>168 ,174
悪りィ、TとUが逆転してるのに気付かんかった。
っていうかテンプレ引数の交換は気付きにくいからやめい。
>>177 やめい、って交換しなきゃ第二引数が省略できんだろ。
>>178 template<class T, class U>
T hoge( U foo )
{
...
}
hoge<int>("できますが何か?");
>>177 ああ、なるほど。混乱させてすまなんだ。
U を使うのって Undeducible か何かの略かと思ってたんで
>>144 と
同じに返値U、引数T、になるようにtemplateの方を変えたんだけど、
Tの次はUってことか。自分では2引数以上のtemplateを書くときは
T1、T2、 T3 ... なのでなぁ。
素朴な疑問なんだけど template<class T, class U> を template<typename T, typename U> とは書かないの?
>>182 個人的には、
・タイプ数減らしたい時はclass。
・template template parameter は class と書くので、
何となく全部 class で統一したい気分の日は class。
・マジメに書くときはtypename。
漏れは最初に覚えたときにclassのみだったから テンプレート引数はclassのみ使用。 typenameは typedef typename T::iterator iterator; とがぐらいしか使わない。
>>184 漏れはtypenameに直した。
ってか,intとかにも対応するのにclassって気持ち悪いんだよな。C++のintはクラスじゃないし。
昨夜、”C++ Templates" をゲット まだChapter 3までしか読んでないけど、なかなか良さげ
>>189 Addison-Wesley だが……出たばっかの洋書でふ
>Addison-Wesley だが… Addison-Wesley キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!! Addison-Wesley、もう大好き♪ 分かりやすいし、詳しいし…。
>>183 俺は int などのプリミティブ型も引数に取る場合には typename, クラスしか
引数に取らん場合には class にしてる。まー、趣味の問題だね。
typename と class は全く同一だと聞いた事があるが・・・どこでだっけ?
本屋行ってみたが、洋書は置いてないと言われた。(´・ω・`)ショボーン 日本訳が出るまで最低1年はかかるからなー。
typename自体が無いしょぼーいコンパイラも世の中には存在する。
>196 まだ使ってるのか… 御愁傷様です。
>>194 全く同一だよ。だからみんなして趣味の問題とか個人的にはとか言ってるわけ。
>>195 出たばっかりの洋書はWebで買った方が良いと思う。
199 :
デフォルトの名無しさん :02/12/05 20:14
boost::lexical_castで、スペースを含む文字列を変換すると例外が 出ますな。 std::cout << boost::lexical_cast<char*>(std::string("abc def")) << std::endl; std::cout << boost::lexical_cast<std::string>("abc def") << std::endl; boost::lexical_castはstd::stringstreamを使って実装しているので、 >>演算子や<<演算子がスペースを区切り文字とみなしてしまう故らしい。 何とかして欲しいですな。
203 :
デフォルトの名無しさん :02/12/08 23:26
落ちそうなので一回ageます。
204 :
デフォルトの名無しさん :02/12/09 00:24
昨日からSTLの勉強をVC++.Netで始めました。 まだ、わかってない部分が多いのですが、質問させてください。 汎用クラスを定義する際、通常のクラス定義のように CSample.h , CSample.cpp のように宣言と定義を別ファイルにはできないのですか? ウィザード利用によるクラス定義(一般クラスの作成手順)を行って、 後で、Template <class T> 文を class CSample 宣言の前につけたり、いろいろしましたが、コンパイルが通りません。 (中間オブジェファイルができません) 結局、定義と宣言を分けないでヘッダファイルのみで全てを記述すれば、OKでした。 実際に汎用クラスを利用する際には、利用箇所によって型決定する事を考えれば 当然のような気もするんですが、そうなんでしょうか? もしそうなら、複数のファイルで、同一の汎用クラスを利用する際は、利用するファイルに、 定義した汎用クラス全文をインクルードすることになるんでしょうか。
>>204 >複数のファイルで、同一の汎用クラスを利用する際は、
>利用するファイルに、定義した汎用クラス全文を
>インクルードすることになるんでしょうか
そうです
>>204 何度もガイシュツだが、exportキーワードを完全にサポートしている処理系
でなければ、template文の宣言と実体を別のファイルに分けて書くことはできない。
もしexportキーワードが有効であれば、実体部をライブラリにできることになる。
やっぱりそうだったんですね。 しかも、ガイシュツとのことで、もうしわけないです。 ありがとうございました。がんばってみます。
物の本によれば、//1の書き方は正しくなく、//2のように書かなければならないと いう意見があるのですが、どちらが正しいのでしょうか。 ちなみにコンパイルはどちらでも通ります(gcc3.2)。 struct Test { template <typename T, typename U> void func(T x, U y) { std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl; } }; int main() { Test t; t.func(1, 1); // as <int, int> t.func(1.1, 2.2); // as <double, double> t.func<int, double>(2, 3.3); //1 t.template func<int, double>(2, 3.3); //2 }
>>208 メンバ関数テンプレートはtと同一のスコープの時は
大丈夫ですが、パラメータとしてtをどこかへ渡すと
t.template と書く必要があります。
>>209 大丈夫なようですが・・・・・意味を勘違いしてるかな?
struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};
void abc(Test& t)
{
t.func(1, 1.1);
}
int main()
{
Test t;
abc(t);
}
>>210 わざわざすみません。いろいろ実験してみたら、下のエラーとコメントしてある
行で、'<'がどうも比較演算子とコンパイラが勘違いしてエラーになるようです。
こういう場合、template限定子を付けて、後に続く'<'が型名のパラメータの
始まりである事を示さなければならないようです。
まだよくわかってないのですが、さらに実験してみます。
struct Test {
template <typename T, typename U>
T test(U x) {
std::cout << typeid(T).name() << ' ' << typeid(x).name() << std::endl;
return static_cast<T>(x);
}
};
template <typename T>
T abc(T x)
{
Test t;
T y;
// y = t.test<T>(x); // エラー
y = t.template test<T>(x);
return y;
}
int main()
{
abc(1.1);
}
>>212 それはコンパイラのバグだと思う…。
> template <typename T>
> T abc(T x)
> {
> Test t;
> T y;
> y = t.test<T>(x); // エラー
だと t の型はtemplateパラメータ T に依存せずに決定しているので、
わざわざ template 限定子を入れる必要はないはず。t の型が T に
依存するなら、test がメンバ関数 template であることはパース時には
わからんから、明示的な template 限定子が必要になるけれど。
例えばもし
> template <typename Y>
> struct Test {
で
> T abc(T x)
> {
> Test<T> t;
だったら、tの型がTに依存するので、必要。
215 :
デフォルトの名無しさん :02/12/09 13:29
漢字のテクスチャを管理するデータ構造を作りたいです。 機能と優先順位は 1.内部で管理しているテクスチャのハンドル数が最大数を超えたら最も古いハンドルを開放する。 2.sjisのコードを指定するとデータ構造からテクスチャのハンドルを検索して返す。 3.ハンドルが存在しなければその時点でテクスチャを生成してそのハンドルを返す。 で、要素の構造体はこんな感じです。 struct{ unsigned short Code; /// 文字コード void *Handle; /// テクスチャハンドル }; 要するにキャッシュの機構なんですがとりあえず hashでインスタンスを、queueで参照を管理するというのを 思いついたんですが他に効率的な方法はありますか?
216 :
bloom :02/12/09 13:40
>>214 いろいろやってみたけど、templateパラメータは現れた順に解決される
みたいですね。
コンパイラはgcc3.2(MinGW)を使ってみたんですけど、やっぱりバグです
かね。プログラミング言語C++第3版§C.13.6、P971を読んでいたら、メンバ
テンプレートの型の推定が不可能な場合、メンバ関数名の次に現れる
"<"を比較演算子と見なしてしまいコンパイルエラーになるような事が
書いてありました。
でもそのような事はまれなので、エラーが生じた場合のみtemplate限定子
を付けるようにしようと思います。
>>204 オソレスだが、次のようにするとVC7でも分割できる。
--- T.h ---
template <typename T>
void print(const T&);
--- T.cpp ---
#include <iostream>
#include "T.h"
template <typename T>
void print(const T& t)
{ std::cout << t << std::endl; }
template void print<int>(const int&);
--- main.cpp ---
#include "T.h"
int main()
{
int i = 10;
print(i);
return 0;
}
> template void print<int>(const int&); template にする意味あんまりないじゃん。
>218 ありがとうございます。動きました。 この場合、T.cpp をコンパイルする際には、実際の利用時の型を T.cpp 内部で明確にし、 それぞれの型別動作をオブジェファイルに記述している。と考えていいんですよね。 main 部に { double d ; print d } を追加するとリンクできないが、 T.cpp に template void print<double>(const double&); を記述すると正常動作したので、 このように解釈しました。
>>219 たしかに、語源的な意味しか残ってないわな。
>>220 おおむね合ってます。「明示的なインスタンス化」っていうやつですわ。
ソースファイル ↓ プレコンパイル ↓ ソース内包オブジェクトファイル ↓ リンク ↓ ソース内包リンクドモジュール ↓ ポストコンパイル ↓ ロードモジュール という方式にすれば、export 対応はそんなに難しくないと思うんだけど・・・。
>222 簡単に逆コンパイルできちゃうような代物だと、そもそも export 使う意味が無いと 思うんだが。速度の話なら pre compiled header って手もあるわけだし。
export って逆コンパイルと何か関係あるの?
225 :
デフォルトの名無しさん :02/12/10 21:38
でさ、、、、 どれが一番速いの?
何の話?
どのライブラリが一番効率よいかってこと。
228 :
デフォルトの名無しさん :02/12/10 21:49
STLport 4.5.3をVC6sp5で使おうと思ってインストールしたんですが、 BoundsCheckerがSTLportのアロケータ(たぶん)みたいなところで メモリリークを検出してくれます。 #include <iostream> #include <string> int main(int argc, char* argv[]) { std::string hello = "Hello, world!"; std::cout << hello << std::endl; return 0; } こんなコードでも1600バイトのリークが検出されます。 _STLP_USE_NEWALLOCマクロを使えば出なくなるんですが、遅くなりそうだなー ってのと、Configuration Manualに When using tools like Purify (c), Codeguard (c) or BoundsChecker (c), it is advised to #define _STLP_USE_MALLOC or _STLP_USE_NEWALLOC, otherwise pointer checking will generally not be available on most STL internal structures, thus defeating the purpose of those tools. とあるので気にしなくていいってことなんでしょうか?
>228 気にするな。
>>228 実際STLportのdefault allocatorは一度確保したら絶対返さない。
> とあるので気にしなくていいってことなんでしょうか?
時と場合で気にしたりしなかったり
allocatorつかったらmallocされっぱなしでも困らないならそのまま
返してくれなきゃ困る場合はSTLP_USE_MALLOCとか
自前でallocator用意すれ
231 :
デフォルトの名無しさん :02/12/11 18:56
Effective STLなかなか良さげ
mapにconst reference operator[]() constって 何で無いの? 毎回const map作って[]使おうとすると怒られるから constはずすってことをつい繰り返しちゃうんだけど・・・。
>>232 std::mapの[]演算子は、対応するキーがないと、自動的に挿入する仕様になって
いるから。その時点で既にconstでは無い。
[]が便利な事は認めるが、できるだけfindとinsertを使おう。例えばstd::multimapには
[]演算子が無い。仕様をよく考えると当然だが、最初この事を知ったとき、STLには
設計ミスがあるのではないかと思ってしまった。
対応するキーがないと自動的に挿入する、という機能が欲しい時に [] を使わない 理由があるの?
>234 効率。
>>235 コード量が増える割には、見合った効果が得られないけど?
初期要素 500,000、試行回数 5,000,000 で試してみた。
挿入が全く発生しない状況でも、1 % 程しか遅くならない。
挿入しか発生しない場合は 5 % 程遅い。
それとも、漏れの書き方が悪い?
int r = large_rand();
map<int, int>::iterator itr = m2.find(r);
if(itr == m2.end())
itr = m2.insert(pair<int, int>(r, 0)).first;
return itr->second;
つーか、233 の 「例えば」 の前後が繋がってないよ。
236のコードを見て気が付いたが、 find,insertではコピーコンストラクタが呼ばれて []演算子だとデフォルトコンストラクタが呼ばれた後に =演算子が呼び出されるんだな。 だからintではなくもっと複雑な型じゃないと差は出ないのかも。 逆に、find,insertでは二回検索するので余計に遅くなりそうな気がするのだが 236の結果を見るとそうでもないのが不思議。
>>238 > find,insertでは二回検索するので余計に遅くなりそうな気がするのだが
漏れも最初そう思ったけど、find が意外に速いんだよね。
ちなみに、[] の実装はこうだったよ。
_Tref operator[](const key_type& _Kv)
{
iterator _P = insert(value_type(_Kv, _Ty())).first;
return ((*_P).second);
}
つまり、236 のコードの、if より下と全く同等。
だから、テストでは find のミスヒット分だけ遅くなったという事だね。
> find,insertではコピーコンストラクタが呼ばれて
> []演算子だとデフォルトコンストラクタが呼ばれた後に
> =演算子が呼び出されるんだな。
上に示した通り共通の動作をしているので、これは違うと思う。
スマソ、勘違いしてた。 何を思ったか[]演算子を使う方に m2[r]=0; みたいなコードを想像してた。 これじゃ動作が違うのに。
>>239 そんなタコな実装ねぇだろ。
その実装だと、
・二回検索することになる
・挿入しない場合にも一時オブジェクトの生成・破棄がおこなわれる。
> そんなタコな実装ねぇだろ。 VC6 に付属の STL をそのままかっぱらってきたんだが・・・。 ところで、どこが 2 重検索になるって?
ほんとだ>VC6 おそろしい。 あ、二回検索にはならねぇな。 236と脳内ブレンドされてたよ。スマソ
* Copyright (c) 1994 * Hewlett-Packard Company だと、 Allocator<T>::reference operator[](const key_type& k) { return (*((insert(value_type(k, T()))).first)).second; } だな。 まぁ、なんだ。たしかに簡潔といえば簡潔だが……
std::mapのoperator[]は特異な存在だけど、便利であるがゆえによく使う。
コードがかさばってでも速い方がいいというなら、C++ を使う理由はない。
STLportのstd::bit_vectorと、Boostのboost::dynamic_bitsetの使い分けは どのようにされていますか?
コードがかさばっても速さと汎用性が両立できるなら、C++を使う理由になる。
> 汎用性 何の話?
>249 スレの趣旨から言って Generic プログラミングだろう(違うか)
251 :
デフォルトの名無しさん :02/12/15 23:10
vc++ver7.0でもtupleは使えない。ok?
252 :
デフォルトの名無しさん :02/12/16 00:45
#include<string> using namespace std; template <typename T> struct dd :public T { typename typedef dd<T>::value_type char_type; inline friend operator<(const dd<T>& a1,const dd<T>& a2 ); //(1) inline friend operator<(const dd<T>& a1,const char_type* a2 );//(2) dd(){} ~dd(){} dd(const char_type* a){ *this=a;} }; template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 ) { return ((const T&)a1 < (const T&)a2); } template <typename T> bool operator<(const dd<T>& a1, const dd<T>::char_type* a2 ) { return ((const T&)a1 < a2); } int main() { dd<string> D("abc"),D2("efg"); D < D2; //(1) OK D < "abc"; //(2) NG } templateのoperatorで (2)のような場合、実装をクラスの中に書くしかないのでしょうか?
253 :
デフォルトの名無しさん :02/12/16 01:04
修正: dd(const char_type* a) { static_cast<T&>(*this)=a; } ですね。 追記: friendなんだからクラス内に実装を書けということなのか、 friendの行を削除したらOKでした。
テンプレートクラスはfriendをメンバに取ることはできないね。
しまった、テンプレートクラスもfriendはメンバに取れるね。逝ってくる・・・
>>252 >>253 うまくいったよ。ddのコンストラクタはexplicit宣言しておかないと、(1)や(2)で
勝手にstd::operator< が選ばれて警告が出る。
template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};
template <typename T> inline bool operator<(const dd<T>& a1,const dd<T>& a2) { return ((const T&)a1 < (const T&)a2); } template <typename T> inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2) { return ((const T&)a1 < a2); } int main() { dd<std::string> D("abc"), D2("efg"); D < D2; //(1) OK D < "abc"; //(2) OK } friend宣言で未解決のテンプレートパラメータがあると、非テンプレート関数として コンパイルされてしまうらしいから、型特定して警告を回避した。
でもまだおかしいや。(2)が実行されてないようです。 template <typename T> struct dd : public T { typedef T value_type; typedef typename dd<T>::value_type char_type; friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1) friend bool operator< <T>(const dd<T>& a1, const typename dd<T>::char_type* a2);//(2) dd() {} explicit dd(const char* a){ static_cast<T&>(*this) = a; } ~dd() {} };
template <typename T> inline bool operator<(const dd<T>& a1,const dd<T>& a2) { std::cout << "dd<T> < dd<T>" << std::endl; return ((const T&)a1 < (const T&)a2); } template <typename T> inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2) { std::cout << "dd<T> < dd<T>::char_type" << std::endl; return ((const T&)a1 < a2); } int main() { dd<std::string> D("abc"), D2("efg"); D < D2; //(1) OK D < "abc"; //(2) OK、しかし実行されない? }
260 :
デフォルトの名無しさん :02/12/16 05:05
>>259 基底クラス(std::string)の operator<(const std::string&, const char*) が
呼ばれているようだな
通常の関数とテンプレート関数が多重定義されている場合、通常の関数が
優先されるからな
261 :
デフォルトの名無しさん :02/12/16 09:57
継承したクラスのオブジェクトは自分自身を指すのだね。 template <typename T> struct dd :public T { typedef typename dd<T>::value_type char_type; friend bool operator<(const char_type* a1, const dd<T>& a2 ) { cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!! return (a1 < (const T&)a2); } dd(){m_str="2ch";} ~dd(){} explicit dd(const char_type* a) { dd::dd(); static_cast<T&>(*this)=a;//なんとm_strにaが入る } private: string m_str; };
template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 ) { cout << "(1)" << endl; return ((const T&)a1 < (const T&)a2); } template <typename T> bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2 ) { cout << "(2)" << endl; return ((const T&)a1 < a2); } int main() { dd<string> D("abc"),D2("efg"); D < D2; //(1) OK D < "abc"; //(2) OK "abc" < D; //(3) OK }
>>261 >cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
m_str は初期化時の空文のままだから、表示されないのは当たり前。
>static_cast<T&>(*this)=a;//なんとm_strにaが入る
そんなわけね〜だろ!
なんか、バカでっかい勘違いしてんぞ
レベルたけぇ・・・(-_-)
int main() { dd<std::string> D("abc"), D2("efg"); D < D2; //(1) OK D < std::string("abc";) //(2) OK } のように、sts::stringの一時変数を作って渡してやらないと、テンプレート関数 の方を呼んでくれない。この当たりがテンプレートの限界なのか。
しかし、ちょっと疑問なのだが、 explicit dd(const typename dd<T>::char_type& a){ static_cast<T&>(*this) = a; } これって一体どこに代入しているの?どうみても自分自身に代入しているように しか見えないのだが・・・・・どんな意味があるのだろう。
基本的な質問です。 More Effective C++のp.16、l2に実際のプログラムでは、このようなクラスはテンプレートになるのだが、 とあります。具体的にはどのように書けばいいのでしょうか?
>>266 なんか激しく気持ち悪い書き方だなぁ。
*(static_cast<T*>(this)) = a;
あるいはすなおに
T::operator=(a);
と書いたほうがわかりやすくないかい?
>>267 たんに、要素の型を int きめうちじゃなくてテンプレート引数で
指定できるようにすべきだ、ってことじゃないの?
>>268 というか、素直にこうだろ〜
explicit dd(const typename dd<T>::char_type& a) : T(a) { }
266です。
>>268 >>270 やっはりそうですよね。分かりやすく書くことを心がけるようにします。
272 :
デフォルトの名無しさん :02/12/16 15:33
dd::dd();//このあとすぐにdd::~dd()が呼ばれてるみたい。 static_cast<T&>(*this)=a;//だからm_strは空白になってる。 なんかすごい勘違いしてたな。絶対変だと薄々思ってたけど... コンストラクタからコンストラクタを呼ぶと直後にデストラクタが呼び出されるのか。 struct A :public string { string m_str; A() { m_str="2ch"; cout << "A::A()" << endl; } ~A() { cout << "A::~A()" << endl; } A(const char* c) :string(c) { A::A(); cout << "A::A(const char*)"<< endl; } }; int main() { A a("stu"); }
>>272 ちょっと違う。A::A(); と書くと、コンストラクタを呼び出したことにはならない。
単にAの一時変数が作成されてすぐに破棄されるだけ。
明示的にコンストラクタを呼び出すには、コンストラクタ初期化子を使う
しかない。
>A(const char* c) :string(c) これ、: m_str(c) の間違いではなくて? こういう書き方あるの?
275 :
デフォルトの名無しさん :02/12/16 18:12
>>273 なるほど!
>>274 A は stringを継承して、メンバも持っているから...。
A(const char* c) :string(c),m_str("m_str")
{
cout << static_cast<string>(*this) << endl;//stu
cout << m_str << endl;//m_str
}
明示的に呼ぶ場合、 this->A::A(); これならOKなのでは?
>>277 できるよ。
#include <iostream>
using namespace std;
struct clsA
{
clsA(){cout<<"clsA():"<<hex<<(unsigned int)this<<endl;}
clsA(int){cout<<"clsA(int):"<<hex<<(unsigned int)this<<endl;
cout<<"CASE:clsA::clsA()"<<endl;clsA::clsA();
cout<<"CASE:this->clsA::clsA()"<<endl;this->clsA::clsA();}
};
void main(void)
{
clsA a(int());
}
>>278 コンパイラは何を使った?Borland-C++5.6.2及びgcc3.2(MinGW)は
エラーが出て通らないけど。
>>279 そうなの?
VC5(苦笑)でつ。
M$オンリーの機能なのか?
エラーはどんなの?
>>280 BCC5.6.2の場合。
エラー E2316 constructor2.cpp 12: 'clsA' は 'clsA' のメンバーではない(関数 clsA::clsA(int) )
gcc3.2(MinGW)の場合。
C:/MinGW/Learn/constructor2.cpp: In constructor `clsA::clsA(int)':
C:/MinGW/Learn/constructor2.cpp:12: parse error before `;' token
というエラーです。
>>281 わざわざTHXです。
…う〜ん。いよいよM$の仕様のような気が。
参考書引っ張り出してもう一度調べてみマフ...
>>282 俺も調べてみるが、確かコンストラクタからコンストラクタを呼び出すには、
初期化リストしか方法がなかったように記憶しているが・・・・どうだったっけな
>>282 どっかのメーリングリストではVC固有の機能だと言われてたな。
>>283 ちょっと話は変わるけど、こんなのどう?
static_cast<T*>(this)->~T();
new(this)T(param);
newで例外が起きるとヤバイが。
>>284 newの配置構文ですね。この場合、デストラクタは自分で呼び出してやらないと
いけないですね。
>>285 そうか?
この場合、Tは(*this) の型の基底クラスだろ
この型のデストラクタがデフォで ~T() 呼ぶから
大丈夫だと思うんだが、どうよ
>>286 ちょっと、目の付け所がいまいち
>>287 そっか。そう言われればそうだな。途中でリコンストラクトした事にはコンパイラ
は気づいてないだろうからね。
>>284 × new(this)T(param);
○ new (static_cast<T*>(this)) T(param);
// こんな感じ? #include <iostream> using namespace std; struct Base { Base() { cout << "Base::Base()" << endl; } virtual ~Base() { cout << "Base::~Base()" << endl; } }; struct Ero : public Base { Ero() { cout << "エロ::エロ()" << endl; } ~Ero() { cout << "エロ::~エロ()" << endl; } Ero(int) { Base::~Base(); new(this) Ero(); cout << "エロ::エロ(int)" << endl; } }; void main() { Ero ero(0); // エロ(0) }
>>291 実行結果が次のようになったのだが、大丈夫だろうか?
Base::Base()
エロ::~エロ() //←これヤバくない?
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()
>>291 // ぜんぜん違うぞ、こうだ
#include <iostream>
class Foo
{
int m;
public:
Foo(int n = 0) : m(n)
{ std::cout << "Foo is created by " << n << std::endl; }
int val() const { return m; }
~Foo()
{ std::cout << "Foo is destroyed. m = " << m << std::endl; }
};
template <typename T> class Bar : public T
{
public:
Bar (int n = 0)
{
std::cout << "Bar is created by " << n << std::endl;
static_cast<T*>(this)->~T();
new (static_cast<T*>(this)) T(n);
}
~Bar()
{ std::cout << "Bar is destroyed." << std::endl; }
};
int main()
{
Bar<Foo>(10);
}
今気づいたが、 テンプレート使う必然性無く、まったくレス違いなネタのような……
>>293 ををををぉぉぉぉなんとトリッキーな。
Fooのインスタンスが先に生成されるのが意外だったけど、これは使えそうだね。
>>292 やばいです。
つーか、うち(VC7)ではこうなりました。
仮想関数テーブルの取り出し方が違うのでしょうか?
Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()
>>293 飛び入りな者でスミマセン。
>>296 >>292 はBorland-C++5.6.2です。
gcc3.2(MinGW)でやったら、次のようなエラーが出てコンパイルできませんでした。
C:/MinGW/Learn/constructor3.cpp: In constructor `Ero::Ero(int)':
C:/MinGW/Learn/constructor3.cpp:20: cannot call destructor `Base::~Base'
without object
gcc3.2(MinGW)は次のようにしたらコンパイルできて、実行結果は以下の通りです。 Ero(int) { this->Base::~Base(); // thisから呼び出すようにした new(this) Ero(); std::cout << "エロ::エロ(int)" << std::endl; } Base::Base() Base::~Base() Base::Base() エロ::エロ() エロ::エロ(int) コンパイラによって実行結果がバラバラですね(^_^;)。
昨日から Modern C++ Design 読み始めたがなんだか 出じゃブーが多いなあ。
Phoenix Singleton とかな(藁
>>298 >コンパイラによって実行結果がバラバラですね(^_^;)。
データレイアウトの違いが原因かも(根拠なし)
>>300 300getしてるよ。
2〜3年前に似たようなこと頑張って考えてた時期あった。
基本型とユザ定義型の区別とか。
コンパイル時のじゃなくて実行時に区別するやつ。
ただしおれは目的があくまでパズルだった。
実用にしようと思ってたらなんか結果出てたかな...?
これって、メモリリークしちゃうの? しないですよね? void foo() { std::vector<std::string> v; v.push_back( *(new std::string("お兄ちゃん♥") ); }
Clear() { for(std::vector<std::string>::iterator it=v.begin(); it!=v.end, ++it) delete &(*it); v.clear(); } とかやらないと駄目なんじゃない?
>>304 (*it)はnewで作成したstringを
コピーコンストラクタでコピーした物だからダメだと思うが。
>>304-305 えっと、つまり、
void foo() {
string* p;
std::vector<std::string> v;
v.push_back( *(p = new std::string("美幸...おまえ...") );
delete p;
}
ってやらなきゃだめ、ってことですか?
>>306 そのコードだと、↓といっしょだな。
void foo() {
std::vector<std::string> v;
v.push_back( "美幸...おまえ..." );
}
うん、えっと、std::vectorが、 「なにを保持してるのか、どう扱えばいいのか」を知りたかっただけなのです。 そか、307見たいに書けるって事は、 「std::vector::push_backは、引数を基にして、 変換コンストラクタかコピーコンストラクタで新しいインスタンスを作って、 そのインスタンスを保持する」 ってことだよね。 新しいインスタンスを保持するんだから、 元のインスタンスは自分で解放する必要がある、と。 やっと心のもやもやが。ありがとうでした。
309 :
デフォルトの名無しさん :02/12/19 09:48
310 :
デフォルトの名無しさん :02/12/19 12:49
次のコードがコンパイルできないんですけどなぜ? #include <iostream> template <class T> struct Hoge { friend void func() { std::cout << "フレンド関数なんだけど" <<std::endl; } }; int main() { func(); } VC7では、「error: C2065: 'func': 定義されていない識別子です」とおこられます。 #定義してあんだけどなあ〜
>>310 'func' なんてどこにも定義してないだろ。
しかし、310 の friend void func() は、どうやって呼べばいいんだ?
template <class T> って書いてある奴の何がグローバルスコープなんだ?
template Hoge<int>; int main() { func(); } かな。ま、func() が何かHoge型の引数をとってくれないと無意味だわな。
ということで310はtemplateのインスタンス化について小一時間勉強すること。
#include <iostream> template <class T> struct Hoge { friend void func<T>() }; template<class T> void func() { std::cout << "フレンド関数なんだけど" <<std::endl; } こうするはず
>>314 template <class T> はHoge に付いているんで、メンバじゃない func() には関係ないと思うけど。
>>315 、
>>316 動きました。でもなぜ?
func() は普通の関数じゃないの? テンプレートじゃない普通の関数をインスタンス化?
> テンプレートじゃない普通の関数 どうしてそう思うのか訊きたいのだが
だから規格書嫁って。 14.5.3 -5- When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template.
>>319 フレンド関数が func() が テンプレート Hoge のメンバじゃない、っていうのは正しいですよね。
Hoge のtemplate <class T> は、クラスそのものとメンバに対してしか影響せず、パラメータに依存しているわけでもない func() とはまったく関係ないはず。
func() 自体も関数テンプレートとして定義されているわけじゃない。
だから普通の関数だと思うんだけど。
>> 316 へえ、普通の関数でも、個別にインスタンス化されるんだ。 勉強になりました。 でも、ということは、インスタンス化されるごとに同じ定義が再生産されることになるの? それってやぱくない? って、VC7はHoge を複数インスタンス化してもエラーになんないな。大丈夫なのかな?
そのネタくさい物言いなんとかしてください。それにこれは どっちかというと相談室の方でやる質問なのでは?
>>323 >そのネタくさい物言いなんとかしてください。
それは正直、すまんかった。きおつけるよ
>それにこれはどっちかというと相談室の方でやる質問なのでは?
template がらみだから、こっちに投げたけど、こんどからはそうするよ。
タイトルは s/template/generics/ のほうがよかったかもね
関数テンプレートの関数のアドレスって取ることができないの? template <typename T> class Hoge { T i; public: Hoge(T t) : i(t) {} friend void func<>(Hoge<T>&); }; template <typename T> void func(Hoge<T>& t) { std::cout << "フレンド関数なんだけど" << std::endl; std::cout << t.i << std::endl; std::cout << reinterpret_cast<long>(&func) << std::endl; } int main() { Hoge<int> h(123); Hoge<int> i(456); func(h); func(i); }
>>326 質問内容と貼り付けるソースを対応させてくれ。
ソースがいろんな(たぶん余計な)要素を含みすぎて
何を答えて欲しいのかがイマイチつかめん。
そのソースでエラーになるんだったら、&func<T>かなー?
>>327 スマソ。いらない要素を除いて短くしました。まだエラーが出ます。
コンパイラはgcc3.2.1(MinGW)です。
template <typename T>
class Hoge {
friend void func<>(Hoge<T>&);
};
template <typename T>
void func(Hoge<T>& t)
{
std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー
}
int main()
{
Hoge<int> h;
Hoge<int> i;
func(h);
func(i);
}
さらに短くしました。friend宣言もクラス宣言も取ってしまいました。 template <typename T> void func(T t) { std::cout << t << std::endl; std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー } int main() { func<int>(1); }
329です。自己解決しました。 テンプレート関数は、コンパイラから関数のオーバーロードと解釈されるようです。 従って、関数名を正しくキャストする事によりうまくコンパイルできました。 template <typename T> void func(T t) { std::cout << t << std::endl; std::cout << reinterpret_cast<long>(static_cast<void (*)(T)>(func)) << std::endl; //うまく行く } int main() { func<int>(1); func<double>(1); func<int>(2); }
んーでも少し問題が。gcc3.2.1(MinGW)では通るものの、Borland-C++5.6.2では エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<int>(int) ) エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<double>(double) ) と言われてしまいました。Borland-C++が糞なのか、それとも私が何か間違っているのか?
332 :
デフォルトの名無しさん :02/12/20 19:03
Modern C++ Design を読んで疑問に思ったので質問します 8章のオブジェクトファクトリのRegisterコールバック関数の登録についてです。 ある具象クラスLine(: public Shape)のソースにおいて const bool registered = ShapeFactory::Instance().Register( LINE, CreateLine ); としてシングルトンのファクトリに登録していますが、 これはファクトリがシングルトンの場合にしかつかえないと思うのです。 動的にファクトリを生成・利用する場合には、具象クラスの情報を一ヶ所にまとめた物がどこかに必ず必要になると思うのですが、 この認識は正しいでしょうか? シングルトンではなく、ファクトリになんの変更も無しに新たな具象クラスを追加する方法があるのでしょうか?
VC.NETのSTLへの対応ってどんなもんなんですか? VC6.0と同じ程度なんですか? sort(v.begin(),v.end(),mem_fun_ref(&hoge::hoge)); ←こんなの通るの?
>>332 Factoryクラスのstaticメンバに情報を持つか、FactoryのFactoryに
情報をまとめるようにして、Factoryの生成をライブラリ側で管理するか、
フリー関数のオーバーロードで頑張るかすれば、一応何とか出来るのではないかと。
しかし、ファクトリがSingletonでないことが必要な場合なら、
各々のファクトリが勝手に情報共有してしまったらむしろ
困ると思うのだけど、具体的にどういう場合を想定してるん?
>>333 > mem_fun_ref(&hoge::hoge)
いやコンストラクタをmem_funに渡せる実装はなかなか少ないだろう。
men_fun1_refにしないでも大丈夫になってるか?という意味なら、VC.NET 2002 ならOK。
>>334 すいません、編集ミスです。<コンストラクタ
しかも、ペーストする場所を思いっきり間違えてました。
質問したいのは、これ(↓)でした。
find_if(v.begin(),v.end(),bind2nd(mem_fun_ref(&Hoge::hoge),HogeObject));
手元にg++用に書かれたコード(STL多用)があり、
これにGUI部分を実装しなければならないのですが、
VC6までは、STLがまともに動かないという話を聞いたことがあるので、
VC.NETではどうなってるのかなと思って質問しました。
やっぱり、BCB6の方が良いでしょうか?
>>334 疑問に思っていたのは以下の2点でした
・「シングルトン」及び「staticメンバに情報を登録」ではプログラムロード時からメモリに存在する。
・ファクトリ側では実行するまでどんな具象クラスが登録されるかを知らない形にし、各具象クラスのcppファイルで登録させる。
プログラムの流れでたまにしか出てこない、いろんな種類のファクトリをはじめからメモリに確保するのが嫌だったのです。
でも実行時に登録するには、
・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
・どこかにリストアップしておく。
のどちらかしか無いように思います。
用語が滅茶苦茶だと思いますがすいません。
>・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要) グローバルはおかしいかな。 cppファイルの頭の部分に書く const bool registered = Singleton::Register(objType,CreateCallback); な感じのやつのことです。
ファクトリの百や二百、メモリを使用してるうちに入らんと思える私は幸せなのでしょうか。
私もです。しかもせいぜい10個くらい。
std::mem_fun_refってどういう時に使う? std::mem_funは、仮想関数を呼び出す時に便利だが、std::mem_fun_refだと クラスへのポインタではなく実体を渡さないといけないので、例えば class A; class B : public A; のようになっているとして、 std::vector<A*> にはBへのポインタも格納できるが、std::vector<A>にBを 格納しようとすると未定義の動作となる。ポインタならばstd::mem_funで 呼び出せる。std::mem_fun_refは実体を渡さなければならないが、vector に両方は格納できない。 だから、std::for_each()などで、std::mem_fun_refを使う状況というのがどう いう場合なのか知りたい。
>>340 Aが派生して使うような型じゃない場合。
>>341 なるほど、こんな場合か。単純と言えば単純だな。
class A {
int j;
public:
void print(int i) {
std::cout << i + j << std::endl;
}
A(int k) : j(k) {}
};
int main()
{
std::vector<A> a;
a.push_back(A(1));
a.push_back(A(2));
a.push_back(A(3));
std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::print), 1));
}
boost::anyと、std::mem_fun_refを使って仮想関数を呼び出そうとしたが なかなかうまく行かない。 int main() { std::vector<boost::any> a; a.push_back(A()); a.push_back(B()); std::for_each(a.begin(), a.end(), std::bind2nd(std::bind1st(std::mem_fun_ref(&A::print), boost::any_cast<A&>(this)), 1)); // だめ }
344 :
デフォルトの名無しさん :02/12/22 05:02
どうしてany_castに失敗するのでしょうか? struct A { void print() { std::cout << "A" << std::endl; } }; int main() { std::vector<boost::any> a; a.push_back(A()); a.push_back(A()); std::vector<boost::any>::iterator pos = a.begin(); try { for (; pos != a.end(); ++pos) boost::any_cast<A>(a).print(); } catch (boost::bad_any_cast& e) { std::cerr << e.what() << std::endl; } }
>>343 試さずに書いてるが、
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
>>344 boost::any_cast<A>(*pos).print();
じゃねーの?
というか、今のバージョンのany_castって継承関係の把握できたっけ。
347 :
デフォルトの名無しさん :02/12/22 09:49
Lokiのインストール法、誰か教えて。 英語読めん。 それと、iostreamをインストールすると、コンパイラ付属のは使えなくなるんか。 それはそれで不安だ。教えてくれ。
>>347 DLして解凍して適当なフォルダに入れてインクルードパス通すだけ
というかあれくらいの長さのreadmeくらい読みなよ…
後環境も何も書いてないからこれ以上は無理
349 :
デフォルトの名無しさん :02/12/22 11:45
Lindows
>>345 ありがとうございます!
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
は通りませんでしたが、
boost::any_cast<A>(*pos).print();
は無事通りました。
boost::any_castは依存関係の把握はできないかもしれませんので、ポリモルフィズム
には使わないようにします。
352 :
名無しさん@Emacs :02/12/22 23:47
げ、ホントだ、any_cast ってポリモーフィズムに使えないんだ・・・ っつーか皆さん boost::any ってどんな時に使ってます? イチイチ any_cast 噛まさにゃならん上にポリモーフィズム使えないもの をどんな風に使うのか興味があるのですが・・・ # つまり馬鹿だから使い道が思い付かないわけでして。 struct A { virtual void print() { std::cout << "A" << std::endl; }}; struct B : public A{ virtual void print() { std::cout << "B" << std::endl; }}; int main() { std::vector<boost::any> a; a.push_back(new A()); a.push_back(new B()); std::vector<boost::any>::iterator pos = a.begin(); try { for (; pos != a.end(); ++pos) boost::any_cast<A*>(*pos)->print(); } catch (boost::bad_any_cast& e) { std::cerr << e.what() << std::endl; } } output> A boost::bad_any_cast: failed conversion using boost::any_cast
>>352 void* で汎用パラメータ渡し…とか、union でノードの種類を区別した
木構造…とかのtypesafeなバージョンとしては、とりあえず超高速で
お手軽に書こう、と思ったときには使えるかも。俺は使ったこと無いけど。
using namespace boost;
struct add { add(any l,any r):left(l),right(r){} any left, right; };
struct mul { mul(any l,any r):left(l),right(r){} any left, right; };
double eval_expr( any e )
{
if( e.type() == typeid(add) ) {
add ex = any_cast<add>(e);
return eval_expr( ex.left ) + eval_expr( ex.right );
} else if( e.type() == typeid(mul) ) {
mul ex = any_cast<mul>(e);
return eval_expr( ex.left ) * eval_expr( ex.right );
} else if( e.type() == typeid(double) ) {
return any_cast<double>(e);
} return any_cast<int>(e);
}
int main()
{
any expr = add( add(mul(6,7),2), mul(3,4) );
cout << eval_expr( expr ) << endl;
}
その手の使い方をするにしても、入れられる型に制限をつけた
variantとかの方がマシだしなぁ。
>>351 any.hppの中身を見てみると、boost::any_castはキャストしようとする型と、
元のタイプのtypeidを比較して、一致しないとキャストしないようになっている。
だからポリモルフィズムに使えないんだろう。
-- any.hpp (STLpotrt)より
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
std::mem_fun_refと組み合わせていろいろと面白い事をやらせようとしていた
のだが、使えねー。まあだめならだめで昨日から悩み続けていた事が解決
したのでいいのだが。
すごく簡単な所でつまづいています。どこがおかしいのでしょうか? class A { public: void func(int i) { std::cout << i << std::endl; } }; int main() { std::vector<A> a; a.push_back(A()); a.push_back(A()); std::for_each(a.begin(), a.end(), std::compose1(std::mem_fun_ref(&A::func), 1); }
自己解決しました。うーん?直感的にはcompose1のような気がするのですが? わからなくなってきた。 class A { public: void func(int i) { std::cout << i << std::endl; } }; int main() { std::vector<A> a; a.push_back(A()); a.push_back(A()); std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::func), 1)); }
358 :
デフォルトの名無しさん :02/12/23 05:26
こんな簡単なプログラムがコンパイルできません。どこがおかしいのか わかりますか?コンパイラはgcc3.2.1です。 int main() { double ad[] = {0.5, 1.0, 1.5}; std::vector<double> d(ad, ad + 3); std::transform(d.begin(), d.end(), std::ostream_iterator<double>(std::cout, " "), std::sin); }
358です。非常に不本意ながら、自己解決しました。 #include <cmath>を#include <math.h>にして、std::sinをsinにすれば通ります。 しかし、ここで当然疑問が沸きます。なぜstd名前空間に包まれているsinが std::transformに適用できないのか、どうしてもわかりません。何のための <cmath>なんでしょうか?
>>356-357 compose1 というのは、返値を h = compose1( f, g ) とすると
h(x) が f( g(x) ) と同じ意味になる合成のことなわけだが。
たぶん貴方の場合、std::mem_fun_ref(&A::func) が2変数関数だし、
1 というのは関数ですらないので全然ダメ。
ついでに1変数メンバ関数用の mem_fun_ref は g = mem_fun_ref( f ) とすると
g(x, y) と x.*f(y) が同じ意味になるもので
bind2nd というのは g = bind2nd( f, c ) とすると
g( x ) が f( x, c ) と同じ意味になるものなので期待通りになる。
>>359 C では double sin(double x); しかないが、C++ では
double sin(double x);
float sin(float x);
long double sin(long double x);
とオーバーロードされてて、どれかわからんので困ってるのでは?
>>361 なるほどありがとうございます。キャストしたら通りました。引数が
doubleだからつい自動判別してくれると期待していたのですが、
アルゴリズム中では正しく働かないようですね。
int main()
{
double ad[] = {0.5, 1.0, 1.5};
std::vector<double> d(ad, ad + 3);
std::transform(d.begin(), d.end(), d.begin(), static_cast<double (*)(double)>(std::sin));
}
363 :
デフォルトの名無しさん :02/12/23 19:22
typedef struct { int id; double value; } BANK; std::list<BANK> blist; みたいなlistがあって、こいつを構造体BANKの中のvalueの値で sortしたい(valueの値が大きい順に)場合、どうしたらよいのでしょうか? blist.sort()を使う方を教えてください!!
>>353 ,354
むむむ、なるほど。情報サンクスコ
なんか大抵の場合はポリモーフィズムかテンプレート使えばいい感じですなぁ・・・
>>853 氏の例をちょっといぢってみたんだけど、 6 を 6.0f にするだけで氏ぬのね。
typeid 使うとこの辺(double, float とかポリモーフィズムとか)が問題になって来るわけか。
なるほど、なるほど。勉強になりますた。
366 :
デフォルトの名無しさん :02/12/23 19:38
>>364 引数の書き方がわからないです。教えてくらはい。
>>366 よーし、SGIのとこからもってきてやったぞ、ホレ。
template<class BinaryPredicate>
void sort(BinaryPredicate comp);
Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements on objects of type T.
This function sorts the list *this according to Comp.
The sort is stable, that is, the relative order of equivalent elements is preserved.
All iterators remain valid and continue to point to the same elements.
The number of comparisons is approximately N log N, where N is the list's size.
>>366 struct BANK {
int id;
double value;
BANK(int i, double d) : id(i), value(d) {}
};
inline bool Cmp(BANK a, BANK b)
{
return a.value > b.value;
}
int main()
{
std::list<BANK> blist;
blist.push_back(BANK(1, 1.1));
blist.push_back(BANK(2, 3.3));
blist.push_back(BANK(3, 2.2));
blist.sort(Cmp);
std::list<BANK>::iterator pos = blist.begin();
while (pos != blist.end())
std::cout << pos->id << ", " << pos++->value << std::endl;
}
369 :
デフォルトの名無しさん :02/12/23 20:03
363、366です。 わかりました!! これで明日のミーティングに間に合いそうです。 みなさんありがとうございました。
C++のSTLには、叙述関数と関数オブジェクトの2種類があって、互いに よく似ているために未だに混同します。 例えば関数オブジェクトは内部状態を持っていてそれを変化させても いいようですが、叙述関数は呼び出しの度に内部状態を変化させては ならないと規定されているようです。 皆さんはどうやって区別していますか?
370です。(゚Д゚)ハァ?なことを書いてしまってすみません。 叙述関数は、ブール値を返す関数または関数オブジェクトでした。 で、やっぱり関数オブジェクトも内部状態を変化させない方がいいの でしょうか?
> 呼び出しの度に内部状態を変化させてはならないと規定 これどこで規定されてんの?
>>372 「規定」と書くと語弊がありますね。C++標準ライブラリ日本語版§8.1.4、P297
に「叙述関数と関数オブジェクトの違い」という節があり、内部状態を変化させ
る関数オブジェクトを叙述関数として使うと、予想に反した動作をする例が書か
れています。
つまり、constな関数オブジェクトでないと、予想した動作ではなくなる可能性
があるという事ですね。
>>373 その記述がすべてだな。「可能性がある」ってんだから、
あとは、場合による、としか言えないんじゃないの。
>>374 簡単にまとめると次のようになりますかね。
叙述関数:
bool値を返す関数または関数オブジェクト。但し、呼び出し毎に内部状態
が変化する関数または関数オブジェクトは、標準アルゴリズムに適用する
と予想に反した動きをする可能性があるので、できるだけ使用しない方が良い。
>>375 まとめるのは勝手だが、
「可能性があるので」が理由じゃぁまとまってるとは言い難い。
>>376 やっぱり「可能性」の具体例をあげないとダメか・・・・
本を読んでくれ、なら簡単なんだが、自分でまとめるとなると、何か例を
考えないといけないか。
関数を提供する側から言えば、 副作用がない、と仮定してアルゴリズムが書かれていると、 述語(ここで言えば叙述関数)を呼び出す回数が予想できないわけだ。 副作用がないなら同じ引数で何度呼んでも値は同じはずだから、アルゴリズムは返り値をメモり、以降その値を使いまわすかもしれない。 (しかし副作用がある関数は呼ばれるごとに値が変わることができるから、メモった値と呼んで帰った値は一致しない可能性がある。) このような性質はアルゴリズム内に隠蔽されていて関数提供側ではまったく予想できない。 一方、逆に標準アルゴリズムを提供する側から言えば、 述語は条件判定に使う関数だから、 例えば副作用がコンテナ内の要素に影響を及ぼす類のものだとすると結果は破壊的になりうるし、そうでなくても同じ対象を比較する際に呼び出すごとに違った値を返すとすると それらを仮定してアルゴリズムを書くのは大変困難だ。 ひどい例を考えてみる。あるコンテナをソートするとする。 そのときにソートの比較に使う述語(if文の中で比較・判別に使われる)が 大小判定ついでにコンテナの値を書き換えるとすると、 どんなアルゴリズムでも大前提(ソート中に値が変化しない)が崩れるから ソートはまずまともに機能しないだろう。 (終わらなくなったり、正しくない結果を返したり・・・。) 述語というのは論理学用語だが、 基本的にif文(あるいはfor文など)の条件式内で条件判定に使われる 特殊な種類の関数をさす用語。 普通、if文の中で代入や入出力などするコードはあまりお行儀が良いとは言えない 分かりにくい保守・変更しにくいコードだという事は納得してもらえると思う。それと同じ。 (エラー処理のように条件が成立したら処理を中止するような場合はともかく。) 一方、述語(叙述関数)は関数オブジェクトの中でも特殊なものなので、 一般の関数オブジェクトの在り様まで規制するものではないから、一般の関数オブジェクトは副作用があっても良い。っつーか、むしろないと困るものもあるくらいだろう。
379 :
デフォルトの名無しさん :02/12/24 09:20
map のコンストラクタで、比較オブジェクトを引数にとるものがあるが、 それの存在意義がわからない。 プログラミング言語C++ 第3版 17.4.1.5 void f(map<string,int>& m) { map<string,int> m2; // デフォルトで < を使う map<string,int> m3(m.key_comp()); // mの比較基準を使う } とあるが、m.key_comp() は less<string> だから、 デフォルトの < を使うのと同じこと。 比較オブジェクトをコンストラタに渡すのが有意義な場合ってある?
>>379 キーが整数として、比較基準を、ある基準値との差の比較とすると、
比較オブジェクトの中に基準値を入れて使うことが想定できる。
struct compare_distance
{
  const int origin;
  compare_distance(int org):origin(org){}
  bool operator() (int rhs, int lhs) const
  {
    return std::abs(rhs - origin) < std::abs(lhs - origin);
  }
};
381 :
デフォルトの名無しさん :02/12/24 09:53
>>380 なるほどね。そういう例はわかります。その比較オブジェクトを渡す
mapの型は map<int, T, compare_distance> ですよね。
map<int, T> つまり map<int, T, less<int> > に、渡せるわけではないと。
これこそ型志向言語の神髄中の神髄、C++が最晩年に到達した 何にも真似のできない世界です。このライブラリに込められた テンプレートの技法は、後世のどの言語もついに超えることが ありませんでした。ですから現在でもこのライブラリはテンプ レートの最高の技術を示した作品であり続けています。 C++の晩年には、テンプレートを駆使した手法は時代遅れとなっ ており、手厳しい非難の対象にもなっていました。しかしC++は テンプレートを捨てることなく、むしろテンプレートの限界を 極めるような作品を数多く生むようになります。その最高の成 果が、この「Loki」で、たった1つの主題の技法の可能性を徹 底的に汲み尽くした(残念ながらC++の死によって未完となって いますが)作品となっています。加えて、ソースにコンパイラ の指定がなく、そのためにVC++版、g++版、Comeau版など、いろ いろでコンパイラに実装が試されています
>383 バッハの『フーガの技法』の解説のパクリかい?
>384 よく知ってるね おれの中では両者の間に連想がある。なんというか厳格さと 柔軟さの混在というか... でももしC++が廃れるようなことがあれば、テンプレートを 魔術的に駆使したものはフーガの技法みたいな扱いを受けそう。
過去の難解言語で為された魔術が 今どういう扱いを受けているか考えてみるといい
387 :
デフォルトの名無しさん :02/12/25 15:00
最近知ったのですが、boost面白そうですねぇ。 俺の場合、STLとかからちゃんと勉強しないといけないけど(笑) ところで、boostのfunctionalとかfunctionって、メンバ関数に対しても使えるの??
388 :
デフォルトの名無しさん :02/12/25 16:44
STLはスレッドセーフですか?そうでないとしたらスレッドセーフなコンテナはありますか?
↑よく知らないけど純粋にテンプレートだけじゃないんですか???
390 :
デフォルトの名無しさん :02/12/25 19:18
>>388 「このコンテナはスレッドセーフである」と規格に書かれてたりは、しないと思う(たぶん)。実装に依存すると考えるべきではないかなぁ?
Effective STL の Item 12 が "Have realistic expectations about the thread safety of STL containers." となっているのでこれを読んでみては?
>>387 メンバ関数は第一引数にインスタンスのポインタを
渡してやればいいから、こんな感じ。
#include <iostream>
#include "boost/function.hpp"
#include "boost/bind.hpp"
struct Test {
int t_;
Test(int t) : t_(t) {}
int Add(char t) {return t_ + t;}
};
int main() {
Test test(5);
boost::function1<int, char> func;
func = boost::bind(&Test::Add, &test, _1);
boost::function2<int, Test *, char> func2;
func2 = &Test::Add;
std::cout << (func)(6) << std::endl;
std::cout << (func2)(&test, 6) << std::endl;
}
393 :
デフォルトの名無しさん :02/12/29 16:46
Boost! ワル カコイイ(・∀・)!
boost::formatの戻り値をchar*として受け取ってメッセージボックスに 表示したいのですがいい方法は無いですか? ()でくくってc_str()とかやってみましたが、 error C2039: 'c_str' : 'boost::basic_format<Ch,Tr>' のメンバではありません。 [ Ch=char, Tr=std::char_traits<char> ] と怒られてしまいます。 MessageBox(NULL, (boost::format("Error !!!\n" "\tlocation %d:%d\n" "\tcode %02x:%02x:%02x:%02x\n" "\tmessage %s\n") % parse_error->get_line() % parse_error->get_row() % parse_error->get_genre() % parse_error->get_category() % parse_error->get_sequence() % parse_error->get_sequence_case() % parse_error->get_message()).c_str(), "error", 0);
(...).str().c_str() しかないんでない?
SGIには感動した! 精子出た! ropeキター
Modern C++ Designの19ページの一番下に紹介されてる 「極めて洒落たテクニック」のソースきぼーん "Sutter"とか"copy constructor"とかで検索したけど みつからんかった...
>>397 Exceptional C++ の項目13。
>>397 Loki::SmartPtr::operator=()を見たらいいやんって書いてあるやん。
400 :
デフォルトの名無しさん :02/12/30 15:40
boost使うとコンパイル劇遅で、ノートな私はVCが死んだかと 思ってしまいます。 コンパイルを早くする方法ってないのかな? templateだからやっぱ無理?
402 :
デフォルトの名無しさん :02/12/30 17:33
>>401 「プリコンパイルヘッダの使用」とかいうやつ?
gcc-3.6ぐらいにはpchブランチの成果が取り込まれるといいな
GenScaterHierarchyについてわからない点。 template <class T1, class T2, template <class> class Unit> class GenScaterHierarchy<TypeList<T1, T2>, Unit> : public GenScatterHierarchy<T1, Unit> : public GenScatterHierarchy<T2, Unit> { ・・・・・ }; 最初の(左側の)基底クラスはGenScatterHierarchy<T1, Unit>としなくても、 template <class T1, class T2, template <class> class Unit> class GenScaterHierarchy<TypeList<T1, T2>, Unit> : public Unit<T1> : public GenScatterHierarchy<T2, Unit> { ・・・・・ }; のようにUnit<T1>でいいのでは?
406 :
デフォルトの名無しさん :03/01/06 02:49
保守
>>405 それだと継承ツリーの途中で Unit<T1> を複数回継承することになって、
コンパイルエラー食らわん?
何かネタない?
411 :
デフォルトの名無しさん :03/01/06 21:02
std::map<int, std::string>に値を挿入するには、 insert(std::map<int, std::string>::value_type(1, "abc")) と insert(std::pair<int, std::string>(1, "abc")) のどちらがより適切でしょうか?
>>411 同じ。mapのvalue_typeは、pairをtypedefしたもの。
>>413 Borland-C++5.6.2でコンパイルしてみた所、同じようなコードを吐いているようです。
コンパイラが違うとバイナリも違ってくるかもしれませんが。
ただ、タイプ量が少ないstd::pairの方が多用される傾向にあると思います。
もっともmap<int, std::string>をtypedefして使えばどちらもあまり変わらないですね。
>>411 insert(std::make_pair(1, "abc"))
416 :
デフォルトの名無しさん :03/01/08 14:25
std::wifstream win("in.txt"); std::wofstream wout("out.txt"); wout << win.rdbuf(); wout.close(); win.close(); マルチバイトを使おうとおもってテストでこれやってみたのですが、 0x81で始まる、日本語がうまく表示されないんですけど ベターな解決策おしえてください。 win2000 vc6 stlport使用 です。
>>415 411です。
遅くなりましたがありがとうございます。make_pairという述語があるのですね。
>>416 stlに関係ないじゃん。(V)C++スレにゆくべきかと。
ちなみにマルチバイトとwchar_tは別物。
419 :
デフォルトの名無しさん :03/01/08 16:59
1)string str="hoge";vector<string> vec; 2)vec.push_back(str); 3)str="fuga"; ここで2)でvectorに追加されているのはstrそのものでしょうか あるいはそのコピーでしょうか? また3)では2)でvectorに登録された内容は上書きされてしまうのでしょうか
>>419 当然コピーです。3)で代入しても、vectorの中身には何の影響も及ぼしません。
>420 ありがとうございます。いろいろ試してみます
>>418 そっかー、そりはショック。
首つって、VCスレいってきます。
ありがとございました。
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/ 1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27 鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
424 :
デフォルトの名無しさん :03/01/08 22:29
保守
>>1 =無職
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
>>296 確かに民放じゃやらないですな。
BSではたまにやるけど。
>>405 またポリタンコですか
あいつどうしようもないですね。
あ、どーしてもいいたかったんだけど、 絶 対 に 有 料 化 し な い で ね 。
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/ 1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27 鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
>>638 そのキャップだけはいろんな意味で許せん。僕によこせ
匿名匿名掲示板自体にクレームがついたんだから2chじゃ出来ないでしょ。。。 連続書き込み規制変えたな きつい。。。
暴力団に殺人依頼した。管理人を入廷時に射殺する
434 :
デフォルトの名無しさん :03/01/09 16:28
age
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 138720人 発行日:2003/1/9
年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。
そんなわけで、年末に予告したIP記録ですが実験を開始しています。
「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
>>589 ちょっと違うが今までがそんな感じだったんよ。
「(善意であろうが悪意であろうが)確認できない以上利用者が真偽を判断すべきであり、
要請があっただけで全て削除するべきではない。」
というのがひろゆきの主張。
嘘を嘘と〜の名言もこれに繋がる。
これに対して動物病院訴訟における地裁・高裁の判断は、
「外部から確認できない以上当事者が中傷だと主張し削除の要請をした場合は、管理人は削除すべき。」
今後はこれに倣い当事者側が中傷だと主張さえすればIP公開する必要が出るかもしれない。
(もちろん警察なり裁判所の正式な提出要請があってからになるだろうけど)
なお、書き込んだ者はその書き込みに対し責任を負うべし、ってのは賛成だが。
いずれにしろ善意の告発は難しくなると思われ。
>>104 と思うんだけど、某○○さんは違うという。。。
>>104 と思うんだけど、某○○さんは違うという。。。
>内容証明が届いて、すぐに削除したら、賠償はしなくていい気が。 それはそのとおりでしょうねぇ。 ・内容証明が届いて、名誉毀損の書き込みがあることを知りえた ・その日から起算してン日間書き込みを消さなかった ・その間のン日間は名誉が毀損されたことによって被害が発生した ということを「裁判所が認めれば」負けちゃうんじゃないかなぁ、、 >んだったら、IP取ってない板で、自分で自分を中傷して、 >すぐに裁判すれば賠償金が取れるってことになっちゃう、、 そのとおりじゃないすかねぇ、、 掲示板の持ち主がけんすうさんだという前提でいうと、 その中傷発言が自作自演かどうか、けんすうさんにも判断できないん だったら、けんすうさんが責任を負わないといけないという判決ですよね。 しかし個人の中傷発言だったら最初から消せばいいのでは。。
ガイドライン読めないのに獣医になれる世の中・・・
2ちゃんねるに近いあるインターネット関連会社の社長は、 2ちゃんねるの幹部から得た話として証言する。 「2ちゃんねるは、運営者や幹部などが それぞれ別々に会社を作りカネの流れを見え難くしているが、 実際の資金源は複数の大手通信会社系からの調査費名目のカネ。 月額で計約700万円と言い、年間にすれば1億円近く。 額はともあれ、これは通信会社系的には、 ぼう大なトラフィックを調査すると言う表向きの理由が一応は立つ。 自社系に都合の悪い書き込みがされた時に優先的に削除してもらうことも期待している」と前置きし 「通信会社系の削除の期待も含めて、2ちゃんねるは総会屋と同じになっている」と言うのだ。
IPでも記録されてみるか。
>>540 鑑定スレでお願いしようとして誤爆し・ま・す・た・!
C++にevalが仕様として盛り込まれるのは何年ぐらいでしょうか?
ぼらんちあさんにお年玉です。 ( ´∀`)ノ~●●●●
447 :
デフォルトの名無しさん :03/01/10 15:36
>>445 cbrtが標準math functionsに組み込まれてから10年は必要です。
名前(アルファベット)五人分入力 ↓ 辞書式に並び替える ↓ "meido.doc"ファイルに書き込む というプログラムを教えてください。 まじ困ってます。
>>441 2ちゃんねらでもPGなれるんだもん・・・。
糞だね。
今後、予想されるレス 「IPって何ですか?」 「串って何ですか?」 「串揚げ」
第3者が見て情報価値の低い書きこみ>「質の低い」
匿名性に絡む問題なので反対 28% 1193 票 サイトのためになるから賛成 54% 2315 票 利用しないから関係ない 8% 378 票 2ちゃんねるってなに? 4% 172 票 アクセスログってなに? 4% 173 票
そーいや boost::shared_ptr が policy 使うよーになるとか ならんとかって話はどーなった?
君がそれやればなんとかなるかも(^_^;)
ますます、ファンタスティックでスリリングでドラマティックなスレッドですわね、
713 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/09 15:33 ID:Jx8vAdAb
というわけで、掲示板の最下部のバージョン表示が20030107a以降のやつは、
ログとり実験やってますです。
今のところ、qb,live2,tmpですね
722 名前:心得をよく読みましょう 投稿日:03/01/09 15:43 ID:b1s0ydcx
qb : 2ch批判要望 削除議論 削除要請 削除整理
live2 : ニュース速報
tmp : ニュース極東 ちくり裏事情 政治思想 Download
厨房! 人権問題 バカニュース 薬・違法
ゴーマニズム ロビー 最悪 少年犯罪
違反の潰し方 ペット苦手 なんでもあり 学歴
IP記録実験PART2
http://qb.2ch.net/test/read.cgi/accuse/1042020193/
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 139038人 発行日:2003/1/10
なにやら、連日メルマガだしてるひろゆきです。
そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。
重くなって落ちたりしてもご愛嬌ってことで。。。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
つうか、2chとアップローダーは関係無いだろに。
雑談系やニュース系の板はIDもIPも関係ないわな
(^^)
ひろゆきはあほ 氏ね
【予告】小学生の登校を狙って・・・
http://live2.2ch.net/test/read.cgi/news/1042035002/ 674 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 23:36 ID:1BXnvYvY
通報する人は、IPはあるので管理者に連絡してくれれば、
「捜査関係事項照会書で照会しますよー」って言ってたて伝えてくださいー。
902 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 23:41 ID:1BXnvYvY
>警視庁の情報提供っていうフォームで通報していいですか?
フォームでもよいかと。
通報者の電話番号とかもきちんとかいといたほうが
取り上げられる可能性高いです。
ホントは110のほうがいいんですが、、
ある object が 型T のインスタンスだったときに true を返す Javascript の instanceof みたいなモノを作ってみたんだけど、 イマイチ使用する場面を思い浮かばない。 なんかイイ使い方があったら教えて下さい
>>464 蛇足ですがinstanceof演算子はJScriptですよん。
>>464 それって
#define instanceof(T, obj) (typeid(obj) == typeid(T))
とか
template<class T> struct instanceof {
static bool f( T ) { return true; }
template<class U> static bool f( U ) { return false; }
};
とかで十分な気がするんだけど、どんなもんを作ったん?
いまいちよくわからん。
>>465 JavaScript 1.3 以上にはあるよ。ECMAの標準にも入ってるし。
>>466 あ、そういえば、それでイイじゃん。つーか、そっちの方がいいかも。
俺が作ったのは、こんなモノ
class __object
{
template< typename Type > struct holder
{
static holder* unique()
{
static holder obj;
return obj;
}
};
public:
template< typename InstanceType > __object( InstanceType& ) throw()
: p_( holder<InstanceType>::unique() )
{}
template< typename CompareType > bool instanceof() const throw()
{ return p_ == holder<CompareType>::unique(); }
private:
void* p_;
};
で、こう使う。
if( __object( obj ).instanceof<T>() ){ ... }
>>467 にミス。
class __object
{
template< typename Type > struct holder
{
static holder* unique()
{
static holder obj;
// ×return obj;
return &obj;
}
...
boost::any みたいなものに組み込めば面白いかなとも思ったけど、
type() があるからいらんわなー。
なんか1日無駄に過ごした気分。フゥ
何を今更・・・
ヤツがアニヲタという事がわかるな。
471 :
デフォルトの名無しさん :03/01/12 02:55
どうしても解決できないので教えて下さい。 struct person{ int id; std::string name; }; struct personless { bool operator()( const person & l, const person & r ) const { return (l.id < r.id); } bool operator()( const person & l, const int & r_id ) const { return (l.id < r_id); } bool operator()( const int & l_id, const person & r ) const { return (l_id < r.id); } }; typedef std::set<person, personless> PersonSet; このとき PersonSet ps; PersonSet::iterator it = ps.find( 5 ); というように、findすると下のようなエラーがでます。 error C2663: 'find' : 2 オーバーロードに 'this' ポインタのための必要な定義がされていません。 これはどうしたら解決できるんでしょうか?
>>471 こんな風にしてもダメ?
struct person {
int id;
std::string name;
person(int i, char* str) : id(i), name(str) {}
};
// 途中略
int main()
{
PersonSet ps;
ps.insert(person(1, "def"));
ps.insert(person(5, "abc"));
PersonSet::iterator it = ps.find(person(5, "abc"));
std::cout << it->id << ' ' << it->name << std::endl;
}
>472 ええと、IDで検索するのが目的なのでこれではちょっと。 int一つ分冗長になるけれど std::map<int ,person> とするしかないのかな。
4nd フォンドボー?
馬鹿が喜ぶだけだからニュースにするなよ
>>474 そのページ既に見てたのですが一番下のコード、コンパイルとおりますか?
ウチの環境VC6+STLportだと
>>471 に示したエラーが出るんです。
って書いてたのですが、Releaseでコンパイルしたら通りました。
デバッグ時にわざわざ
#define_STLP_DEBUG 1
を定義してたのがダメだったようです。コメントアウトしたらデバッグでも
コンパイル通りました。
納得いかないけど解決手段として _STLP_DEBUGを使うのはあきらめます。
>>473 std::setのfindはkeyそのものを探すので、IDで検索したければ、
std::mapのようにkeyとvalueが分離されているコンテナを使った
方がよい。std::setは明らかに不適。
479 :
デフォルトの名無しさん :03/01/12 11:41
Loki::Private::ConversionHelperだけど MCD本39ページ解説の通りになってるけど 型"U"がコピーコンストラクタをprivateにしてたらコンパイルエラーだよね? static Small Test(U); じゃなくて static Small Test(U&); にすればいいと思うんだけどダメなのかな?
まあちゃんとしたのが使いたければboost/type_traits/is_converson.hpp を使えってことなんだろうね。Lokiはそもそも教育用のサンプルなんだし。 それにしてもboostのソースはLokiよりも読むのにえらい時間がかかるなあ。
s/converson/convertible/ 二重に間違えてスマソ
>>471 std::setのメンバ関数のfindは使えないけど、こんなのはどうだ。
struct person {
int id;
std::string name;
person(int i, char* str) : id(i), name(str) {}
bool operator==(int i) const {
return id == i;
}
};
// 中略
int main()
{
PersonSet ps;
ps.insert(person(1, "def"));
ps.insert(person(5, "abc"));
PersonSet::iterator it = std::find(ps.begin(), ps.end(), 5);
std::cout << it->id << ' ' << it->name << std::endl;
}
あるいは、==演算子をオーバーロードするのが気持ち悪ければ、次のように。 struct person { int id; std::string name; person(int i, char* str) : id(i), name(str) {} }; class cmp { int key; public: cmp(int i) : key(i) {} bool operator()(person& p) const { return key == p.id; } }; // 中略 int main() { PersonSet ps; ps.insert(person(1, "def")); ps.insert(person(5, "abc")); PersonSet::iterator it = std::find_if(ps.begin(), ps.end(), cmp(5)); std::cout << it->id << ' ' << it->name << std::endl; }
487 :
デフォルトの名無しさん :03/01/12 19:01
VC6だとunsigned char* から char* に変換できませんとエラーが でるんだが、VC++.NETだとエラーにならない。...バグなのかなぁ? #include<sstream> #include<vector> using namespace std; struct a { stringstream _Base; template<typename _Alloc> void operator>>(std::basic_string<unsigned char, std::char_traits<unsigned char>, _Alloc>& str) { std::basic_string<char, std::char_traits<char>,_Alloc > strbuf; ( (*this) >> strbuf);//////ここ str= reinterpret_cast<const unsigned char*>(strbuf.c_str()); } template<typename _Alloc> void operator>>(std::basic_string<char, std::char_traits<char>, _Alloc>& str) { _Base >> str; } }; int main() { a A; basic_string<unsigned char> str; A >> str; }
>>587 gcc3.2.1だとエラーが多くてコンパイルできない。何とかしてくれ。
このスレカコイイ!
490 :
デフォルトの名無しさん :03/01/12 19:33
#include<sstream> #include<vector> class A { public: std::stringstream _Base; template<typename _Alloc> void operator>>(std::basic_string<unsigned char, std::char_traits<unsigned char>, _Alloc>& str) { std::basic_string<char, std::char_traits<char>,_Alloc > strbuf; ( *this >> strbuf);//////ここ str.assign(reinterpret_cast<const unsigned char*>(strbuf.c_str())); } template<typename _Alloc> void operator>>(std::basic_string<char, std::char_traits<char>, _Alloc>& str) { _Base >> str; } }; int main() { A a; std::basic_string<unsigned char> str; a >> str;//(1)NG ->エラー std::string str2; a >> str2;//(2)OK }
491 :
デフォルトの名無しさん :03/01/12 20:11
boostのsmart_ptr全般で、boolへの暗黙の型変換をするとき、 なんでこんなヘンなことやってるの? operator bool()ではいけないんですか? // implicit conversion to "bool" typedef T * (this_type::*unspecified_bool_type)() const; operator unspecified_bool_type() const // never throws { return ptr == 0? 0: &this_type::get; }
いや、最近のニュー速は本当に良くなってきたと思うよ。 ニュース速報板だからね。
・・・横槍。 削除依頼を内容証明以外の方法で行っても有効ですが、条理が根拠ではありません。 意思表示の一般原則であり自明のことです。 免責の対象にはならないから安心してください。
>>491 smart_ptr p;
int x = p + 1;
こんなクソコード書く奴にコンパイルエラーを叩きつけるため。
gannbattekudasai
>>494 おっと、入れ違い。
そうか、intになってしまったら*+-/なんかの演算子が許されるのか・・・
今改めてそのスレッド追うの面倒なので記憶に頼って書くけど、 > ・private:operator int()してもダメ。->なんで? これは結構いいんでない?という結論になったのでなかったか。 smart_ptr p; cout << p << endl; がコンパイル通ってbool値を表示してしまうという問題はあるけれど。
499 :
デフォルトの名無しさん :03/01/13 01:23
こんな簡単なコードが通りません。 std::basic_string<unsigned char> str; const unsigned char* p = (const unsigned char*)"abc"; str = p; //もしくはstr.assign(p); どおして通らないのかどなたかわかりません?
unsignedは何か意味があるの?
>>500 >>487 >>490 のリストをgccでコンパイルするとエラーになるので、エラーが再現
する最小のプログラムを探していったら
>>499 になりました。
単にstd::basic_stringをunsigned charで型特定しただけなのになぜエラーが
出るんでしょうね?
bits/basic_string.h見てもよく分からんね。 なにか基本的なことがわかってないっぽい<自分
だから、どんなエラーがでるんだよ。
ホゥ、世の中には、「リンクエラー」以上の情報を 報告しようとしない変態リンカが存在するのか、、、 デバッグもさぞ大変な事だな、、
undefined reference to `std::char_traits<unsigned char>::length(unsigned char const*)' undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)' undefined reference to `std::char_traits<unsigned char>::move(unsigned char*, unsigned char const*, unsigned)' undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)' undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)' undefined reference to `std::char_traits<unsigned char>::move(unsigned char*, unsigned char const*, unsigned)' undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)' です
$ g++ -v gcc version 2.95.2 19991024 (release) では、ちゃんとコンパイル・リンクできたが。
>>506 書いてあるとおりだと思うが。std::char_traits<>::xxx() ってテンプレート
関数を unsigned char で特殊化したものを用意しろ、ってことだろ。
これってgcc3.xのbits/char_traits.hバグ? それともSTLの仕様? バグならバグレポート書きたいのだけど。
> バグならバグレポート書きたいのだけど。 そのレベルの人間は、規格書をチェックでしょう。
>>508-511 499です。
charとwcahr_tで型特定されているのは、多分効率を重視するためでしょうね。
その反面、basic_stringで独自の型を用意しようとすると、assign()などのメンバ
を自分で用意してやらないといけなくなったと。
これで、悩まずに済むようになりました。ありがとうございました。
Borland-C++5.6.2では、basic_stringにunsigned charを指定してもエラー にはなりません。それは、多分型特定してないからですね。 Include\stl\string.hを見てもそれらしい型特定はありません。 Borland-C++5.6.2はSTLportなので、確実な事は言えませんがgccでも STLportを導入すればunsigned charの問題は回避できるような気がします。
(^^)
こんなアホサイトに人生振り回される奴もどうかしてるがな
こういうのって loki にはないですか? template<int v> struct Int2Type{ public: enum { Value = v }; }; template<typename T1, typename T2, bool isT1GreaterThanT2> struct SizeCompareRaw { typedef int Greater; typedef int Lesser; }; template<typename T1, typename T2> struct SizeCompareRaw<T1, T2, true> { typedef T1 Greater; typedef T2 Lesser; }; template<typename T1, typename T2> struct SizeCompareRaw<T1, T2, false> { typedef T2 Greater; typedef T1 Lesser; }; template<typename T1, typename T2> struct SizeCompare{ typedef SizeCompareRaw<T1, T2, Int2Type<(sizeof(T1) > sizeof(T2))>::Value >::Greater Greater; typedef SizeCompareRaw<T1, T2, Int2Type<(sizeof(T1) > sizeof(T2))>::Value >::Lesser Lesser; }; typedef SizeCompare<SizeCompare<int, char>::Greater, long long>::Greater GreatestType; もしあったら、もっと単純できれいな実装でしょうか?
>>516 何がしたいのか、日本語で書いてみないか?
>>516 > loki にはないですか?
Loki は小さいから自分で調べてみるとよろし。
少なくとも俺の記憶では、そのものズバリは無いんじゃないかと…
> もっと単純
Int2Type 使わなくともいいと思う。
あと、1番上の SizeCompareRaw の定義はいらない。
Loki::Select を再利用するとか…
template<class T, class U> Large {
typedef Select<sizeof(T) > sizeof(U), T, U>::Result Result;
};
(^^)
520 :
デフォルトの名無しさん :03/01/15 18:34
式templateとかで静的な値を得るのに 特別な技法を使うんじゃなく、 構文が使えたら便利だよね。 (回りくどい表現になりがちだから。)
みなさんレスありがとうございます。
>>517 サイズの大きい方の型を得たかったのです。
>>518 上のソースが、Modern C++ を読んでから自分ではじめて考えた
generative 風のコードなので
(モダ++に)解説されている範囲外は、ソース見ても、まださっぱりなんですよ^^;
(見ても求めているものかどうかよくわからないんです、試せばいいのですが…^^; 本格的に g++ に乗り換えかな…)
これから少しずつ精進していこうと思います。
Int2Type を使わないで書くとどういう感じなのでしょう?
さっぱり思い当たらないのですが、ヒントだけでもいただけないでしょうか?
>>520 host-policy とかも、文法レベルでサポートしてほしいですよね。
loki を見てると、ライブラリでやる範疇をそろそろ超えているような気が…
(いい意味で捕らえると C++ の(これまでの)限界を打ち破る力だと思うのですが…)
523 :
デフォルトの名無しさん :03/01/16 12:47
教えてください。 tupleのvectorをtupleの第1要素でソートしたいときどうしたらいいんでしょう。 typedef boost::tuple<int, double> Tuple; std::vector<Tuple> data; // data.push_back(boost::make_tuple(1, 1.0)); .... std::sort(data.begin(), data.end(), boost::bind( std::less<int>(), boost::bind(boost::mem_fn(&Tuple::get<0>, _1), boost::bind(boost::mem_fn(&Tuple::get<0>, _2) )); これだとコンパイル通りませんでした。 (BCB6で「コンパイラ内部のエラー」) なんか間違ってるでしょうか。 それか、こういう場合もっと簡単な方法があるんでしょうか?
何気に難しいな、どうやるんだろ
力ずくで良いなら struct CompByTuple1st { bool operator()(const Tuple& t1, const Tuple& t2) { return t1.get_head() < t2.get_head(); } }; を比較用の関数オブジェクトとして sort に渡す、かねぇ。汎用性ゼロ だが。
>>523 それであってる (gccなら通る) 。…が、その場合 mem_fn はなくてもOK。
BCBでまともに boost::bind を動かすのはあきらめた方が無難ではないかと。
527 :
デフォルトの名無しさん :03/01/17 10:33
皆さんありがとうございました。BCBでbind系が使えるようになる日を待ちます。 とりあえず、比較オブジェクトをtemplateにして template <typename T, int I> struct CompareByNth { bool operator()(const T & a, const T & b) const { return a.get<I>() < b.get<I>(); } }; で逃げることにしました。これにstd::lessを簡単に渡せればいいんですけど…
>>526 gccで通った?俺はg++3.2.1で試してみたが、
C:/MinGW/Learn/boost/tuple.cpp:18: no matching function for call to `mem_fn(
<unknown type>, boost::arg<1>&)'
C:/MinGW/Learn/boost/tuple.cpp:19: no matching function for call to `mem_fn(
<unknown type>, boost::arg<2>&)'
C:/MinGW/Learn/boost/tuple.cpp:21: parse error before `;' token
なんてエラーが出やがる。
g++も駄目か
>>528 あーほんとだ。523のをコピペじゃなくて書き写したんで、微妙に
違うコードをコンパイルしてたわ。
sort( data.begin(), data.end(),
bind( less<int>(),
bind( mem_fn(&Tuple::get<0>), _1),
bind( mem_fn(&Tuple::get<0>), _2) ));
//mem_fnは無くてOK。
532 :
デフォルトの名無しさん :03/01/19 15:53
std::accumulateを使ってプログラムを書いてみたのですが、何かこうもっと スマートに書けないものでしょうか? struct A { virtual int func() { return 1; } }; struct B : public A { int func() { return 2; } }; int AddA(int i, A* a) { return i + a->func(); }
533 :
デフォルトの名無しさん :03/01/19 15:53
int main() { std::vector<A*> a; const int maxi = 100000; for (int i = 0; i < maxi; i++) if (std::rand() % 2) a.push_back(new A); else a.push_back(new B); int i; std::accumulate(a.begin(), a.end(), 0, AddA); std::cout << i << std::endl; }
>>533 back_inserter と generator 使うと、もっとうまく書けそうな予感。
うーんこれでもまだ不格好だ・・・・ struct Add { int value; Add(int i) : value(i) {} void operator()(A* a) { value += a->func(); } }; int main() { std::vector<A*> a; const int maxi = 100000; for (int i = 0; i < maxi; i++) if (std::rand() % 2) a.push_back(new A); else a.push_back(new B); int i; i = std::for_each(a.begin(), a.end(), Add(0)).value; std::cout << i << std::endl; }
>>534 back_inserterを使うという事は、他のvectorに値を入れるという事でしょうか?
できました。もう一個vectorを使ってやってみました。こんな感じでしょうか? int main() { std::vector<A*> a; std::vector<int> b; const int maxi = 100000; for (int i = 0; i < maxi; i++) if (std::rand() % 2) a.push_back(new A); else a.push_back(new B); std::transform(a.begin(), a.end(), std::back_inserter(b), std::mem_fun(&A::func)); int i; i = std::accumulate(b.begin(), b.end(), 0); std::cout << i << std::endl; }
さらにアルゴリズムを使ってみました。私にはこの辺が限界です。 inline A* gen() { return (std::rand() % 2) ? new A : new B; } int main() { std::vector<A*> a; std::vector<int> b; const int maxi = 100000; std:generate_n(std::back_inserter(a), maxi, gen); std::transform(a.begin(), a.end(), std::back_inserter(b), std::mem_fun(&A::func)); int i; i = std::accumulate(b.begin(), b.end(), 0); std::cout << i << std::endl; }
もう一個vectorなんて、許さん。 #include <boost/iterator_adaptors.hpp> int accumulate( const std::vector< A* >& v ) {     std::mem_fun_t< int , A > func( &A::func );     return std::accumulate(   boost::make_transform_iterator( v.begin() , func )                             , boost::make_transform_iterator( v.end() , func )                             , 0 ); }
gcc2.95を使ってるんだけど、ちょっと複雑なテンプレートで すぐにInternal compiler errorを吐きやがります。 VC6は食います。 そんなもんですかね。
>>539 すげー!こんなコードが書けるのか。
やっぱりSTLやboostは奥が深いですねえ。
>>540 VCも使ってるって事は、gccはcygwinかMinGW?
>>542 YES YES YES
gcc3,VC7ではもちろんとおります
>>543 gcc2.95.2にこだわる理由は何?
もしかして仕事で使っているとか?
>>538 std::vector<A*> a を generate_n で作るまでは OK として、その後は
std::accumulate(v.begin(), v.end(), 0,
boost::compose_f_gx_hy(
std::plus<int>(),
std::identity<int>(),
std::mem_fun(&A::func)
));
ってな感じでどう?
>>539 うまいな。そっちの方が見やすいかもしれん。
>>540 template 使いたいなら gcc 3 系列に移行しましょう。
…俺も仕事でいまだに gcc 2.96 使ってるけど、早く捨てたい。
趣味だったらVC7/GCC3にするって。 仕事なんでVC6/GCC2.95を使わざるをえません。 あれからいろいろいじったけど、 どうやってもgcc2.95で通らないんだな。 vc6は、使うものしか処理しないって感じだねえ。 gcc2.95は、使おうが使うまいが、ある程度処理するみたい。 落ちてるところは実際には使われない部分だったりするからナントモ。
>>545 std::identityってのは初めて見ました。ここの文脈ではint()とは書けないから
必要なんですね。標準C++には無いようですが、STLportには幸いにも装備
されていました。
ところでg++3.2.1でstd::identityがエラーが出るのですが、boostには これの代用になる物がありますか?
>>549 簡単なものだから、自分で書いちゃっても。
これは要するに
f(x) = x
となるような恒等変換をする関数オブジェクト。
namespace std {
template <typename T>
struct identity : public unary_function<T, T>
{
T& operator()(T& x) const { return x; }
const T& operator()(const T& x) const { return x; }
};
}
>>550 なるほど、関数オブジェクト化すればよかったのですね。
ありがとうございます。
552 :
デフォルトの名無しさん :03/01/19 18:51
template<bool Val> struct A{ template<class T> struct B{}; }; template<class T1,class T2> struct C{ typedef A<sizeof(T1)==sizeof(T2)>::B<T1> type; }; main(){ A<sizeof(int)==sizeof(int)>::B<int> val1; // ここはエラーにならない C<int,int>::type val2; // ここでエラー } これって文法的にはどうなんでしょうか? VC7とDigital Mars C++では通るのですが、 去年の夏ごろのmingwではコンパイラ内部エラーになり、 冬に出たmingwでは内部エラーにはならないもののコンパイルできないのです。
vectorクラスにpush_backしたらポインタがふっとんでがびーん
ようやく最小限のコードになったよ・・・ ----- // gcc2.95(cygwin)でinternal compiler error template<typename T> struct A { T* pT; }; //template<typename V> struct B { template<typename T> struct C : public A<T> { void func(T* pT) { return; } }; }; ----- 中央のコメントアウトしたのを外すと通し、使える。 ひょっとして外出?
>>554 手元の処理系で試してみたけど
× gcc version 2.95.4 20020320 [FreeBSD]
○ gcc version 2.96-ee-001003-1
○ gcc version 3.2 (mingw special 20020817-1)
ってことで gcc 2.96 で修正済みのバグと思われ。
>>555 検証サンクス。gcc2.95そのもののバグなのね。
とりあえずB<void>でworkaroundしときます。
これでようやくVC6と合わせられる・・・
557 :
デフォルトの名無しさん :03/01/20 16:08
stlのmapコンテナで map<string,int> WD; としている時に mapのsecondの値(int)の大小を比較して大きい順にソートするよい方法って ないですか? 最終的にはそのソートされたfirst(string)を順番に表示したいのですが。
>>557 firstとsecondを逆にして他のmapに挿入し直す。
559 :
デフォルトの名無しさん :03/01/20 16:24
>>557 ありがとうございます。
intをキー値に持つマップに格納してみます。
STLportのstd::mapとstd::hash_mapの速度がどれくらい違うか実験してみました。 コンパイラはBorland-C++5.6.2です。 hash_map insert(10) = 107 map insert (10) = 114 hash_map lookup(10) = 48 map lookup (10) = 29 hash_map insert(100) = 486 map insert (100) = 708 hash_map lookup(100) = 289 map lookup (100) = 277 hash_map insert(1000) = 5395 map insert (1000) = 7743 hash_map lookup(1000) = 2593 map lookup (1000) = 3586 hash_map insert(10000) = 54202 map insert (10000) = 93014 hash_map lookup(10000) = 28221 map lookup (10000) = 54862 hash_map insert(100000) = 839600 map insert (100000) = 1476372 hash_map lookup(100000) = 335070 map lookup (100000) = 1084240 hash_map insert(500000) = 3934177 map insert (500000) = 9722710 hash_map lookup(500000) = 1835211 map lookup (500000) = 7610511 予想以上の差に驚いています。要素の数が増大すればする程差が開いて 行きますね。
561 :
デフォルトの名無しさん :03/01/20 22:11
boost::function1<bool,int,int> とか boost::function1<int,int,int> とかを まとめてvectorとかに入れたいんだけど、どうすればいいかな?
562 :
デフォルトの名無しさん :03/01/20 22:13
563 :
デフォルトの名無しさん :03/01/21 10:35
>>558 さんの言うとおりに<string, int>の新しいマップ関数を定義して
firstとsecondを入れ替えてみたのですがこれを出力すると
intの数値が同じものはstring部がすべて表示できませんでした。
このように数値が重複しているものでも別々に出力するにはどうすれば
いいのでしょうか?
>564 そのくらいは自分で分かるようになりなよ…。 そもそも連想配列が分かってないんじゃ?
>>564 int main()
{
std::map<std::string, int> si;
si["abc"] = 1;
si["def"] = 1;
si["ghi"] = 2;
std::multimap<int, std::string> is;
std::map<std::string, int>::iterator sii;
for (sii = si.begin(); sii != si.end(); ++sii)
is.insert(std::make_pair(sii->second, sii->first));
std::multimap<int, std::string>::iterator isi;
for (isi = is.begin(); isi != is.end(); ++isi)
std::cout << isi->first << ' ' << isi->second << std::endl;
}
568 :
デフォルトの名無しさん :03/01/23 00:03
gcc (GCC) 3.2 20020927 (prerelease) on Cygwin(1.3.18-1)でコンパイル通らないんですけど何故に? ちなみに1次元配列なら全然問題ないんスけど。教えてぷりーず。 #include <vector> using namespace std; int main() { vector<vector<int> > IntAry; IntAry.assign(5);// 5 x 6 array for(int i=0; i<IntAry.size(); i++) IntAry[i].assign(6); }
>>568 コンパイルエラーを省くなとあれほど・・・・
>>568 vector.assign(int)というメンバ関数はないっス・・・・・・
>>568 vector<vector<int> > IntAry(5, vector<int>(6, 0));
573 :
デフォルトの名無しさん :03/01/23 05:28
getch( )の( )って何のタメにあるの? 中に何か入るの?
おまいら、アホみたいに頭いいな。感動した。
>>573 関数のプロトタイプないし呼び出しにて、「引数が何も無い」 事を示している。
括弧をつけないと、関数のプロトタイプないし呼び出しではなく関数へのポインタを得る事になる。
(^^)
>>578 std::vectorには、vector c(n, elem) というコンストラクタがある。
elemの要素をn個コピーして初期化する。
って書かなくてもわかるよね。
いい加減にboostをSTLに組み込めと。
いい加減にboostをSTLに組み込めと。
いい加減にboostにSTLを組み込めと。
あっboost「に」STL「を」組み込むのか。なぜそんな事をする必要があるの? そうなったらstdのコンテナは使わないって意味?
Loki::SmartPtrのOwnershipパラメータ用Lokiが定義してるポリシーのうち、 Loki::RefCountedMTだけテンプレートパラメータの数が違う気がするんですが、 これでいいんですか? gccだとコンパイル通りませんが。 int main(void){ Loki::SmartPtr<int, Loki::RefCountedMT> p; return 0; } 過去ログ一応見ましたが、がいしゅつだったらご免なさい。
587 :
デフォルトの名無しさん :03/01/26 00:05
今、boost の weak_ptr のソースを読んでいて、 (文法レベルで)ちょっとわからない事があったのですが、 コンストラクタの引数の template<typename Y> weak_ptr(weak_ptr<Y> const & r) という書き方、これは一体何を表しているのでしょうか? 生のポインタなら Y* const はわかるのですが、それって対応するのは weak_ptr<const Y> ですよね? ポインタ自体が const なら const weak_ptr<Y> ですよね? weak_ptr<Y> const& っていうのは何を表しているんでしょうか?
>>587 const AAA &
と
AAA const &
は同じ意味。
>>588 ななななんと!知りませんでした…。そんな書き方ができるとは…。
ありがとうございました。読みづらい…鬱だ…。
質問続きでスミマセン。
VC++6.0 で boost::mem_fn を自作スマートポインタに適用しようとしたら
C:\Program Files\Microsoft Visual Studio\VC98\include\xmemory(34) : error C2660: 'new' : 関数が不正な 2 個の実引数をともなって呼び出されました。
C:\Program Files\Microsoft Visual Studio\VC98\include\xmemory(66) : コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::_Construct(MyPtr<PointeeType> *,const MyPtr<PointeeType> &)' の参照を確認してください
みたいなエラーになりました。何がいけないか以上の情報でわかる人いますか?
ちなみに同じ状況で自作スマートポインタを boost::shared_ptr に変えると
コンパイル通るのです。
>>590 激しく鬱ですね…。ポインタが全て Ptr<PointeeType> みたいな書式になって
配列を int[] num; みたいに書ければ const が全て直後の型に掛かる。で統一できるのに…。
593 :
デフォルトの名無しさん :03/01/26 10:52
VisualStdio6.0を使っていますがexportが使えないようなのですがそれに代わるものは何かあるのでしょうか?
export が使える処理系って、comeau くらい? って、使ったことないけど。 で、プログラム内でのそのテンプレートの使い方が限られているなら 明示的インスタンス生成ですな。
>>592 そのガイドラインの評価ってどうなってんの?
596 :
デフォルトの名無しさん :03/01/26 13:12
重複チェックをする場合としない場合の両方に対応する必要があるプログラムを作成しています。 そこでSTLのsetとmultisetを使おうと思って以下のように書いたんですが、 ソースのいたるところでif(cyofukuOK)の分岐だらけになってしまってます。 もっといい方法ないでしょうか? set<AnsiString> setContainer multiset<AnsiString> multiContainer //以下略 if(cyofukuOK) multiContainer.insert(tmp); else setContainer.insert(tmp);
>>596 multisetを操作するラッパーを作ればいいんじゃねーの?
>>596 std::set, std::multiset を直にコードに埋めずに、
1) std::set を保持し、それを操作するクラス。
2) std::multiset を保持し、それを操作するクラス。
と二つに分けてしまう。
Set* pSet;
if (cyofukuOK)
pMap = new MultiSet();
else
pMap = new UniqueSet();
struct Set {
virtual void insert(AnsiString) = 0;
...
};
class UniqueSet : public Set {
std::set<AnsiString> container_;
public:
void insert(AnsiString s) { container_.insert(s); }
};
class MultiSet : public Set {
std::set<AnsiString> container_;
public:
void insert(AnsiString s) { container_.insert(s); }
};
599 :
デフォルトの名無しさん :03/01/26 14:31
596です。 598さん、ありがとうございます。 早速やってみました。 コンテナに保持するまではうまくいったのですが、 iteratorはどうやって保持すればいいんでしょうか? 以下のようにすると特化パラメータを指定しろというエラーメッセージが出るのですが、よくわかりません。 forで使うのでbegin(),end()も必要なんでしょうかね?やはり・・ struct mySet { virtual void insert(AnsiString) = 0; virtual iterator getiterator(void) = 0; }; class UniqueSet : public mySet { std::set<AnsiString> container_; std::set<AnsiString>::iterator itrator_; public: void insert(AnsiString s) { container_.insert(s); } iterator getiterator(void) { return itrator_; } }; class MultiSet : public mySet { std::multiset<AnsiString> container_; std::multiset<AnsiString>::iterator itrator_; public: void insert(AnsiString s) { container_.insert(s); } iterator getiterator(void) { return itrator_; } };
600 :
デフォルトの名無しさん :03/01/26 14:32
596です。 ちなみに現状はこんな感じです。 typedef set<AnsiString> SetContainer; typedef SetContainer::iterator SetIterator; SetContainer Container ; if (cyofukuOK) { for(SetIterator it=Container.begin();it!=Container.end();++it) TRichEdit1->Lines->Add(*it); { else { 以下略 }
おはよう(?)ございます。
>>592 か、書いてませんでした。下記のような感じのオーバーロードでいいのでしょうか?
namespace boost
{
template <typename T>
T* get_pointer(const MyNamespace::MyPtr<T>& smartPtr)
{
return &(*smartPtr);
}
}
ちなみにこれを書いてもエラーメッセージは何も変わりませんでした。
よろしくお願いします。
>>599 > 以下のようにすると特化パラメータを指定しろというエラーメッセージが出るのですが、
そりゃ
> iterator getiterator(void) { return itrator_; }
ここの戻り値の型である iterator ってのが、テンプレート型だからでしょ。クラス定義
の中に
typedef std::set<AnsiString>::iterator iterator;
とでも追加しとかんと。
603 :
デフォルトの名無しさん :03/01/26 15:11
ちょっと質問。 vector<T> vec; が格納している要素列の先頭アドレスを得るのに &vec[0] とやると思うんだけど、この操作は、vec.empty() == true の時も有効でしょうか。
>>604 &vec[0] に「書き込む」のはダメだが、&vec[0] を取得するのは問題ないと思うぞ。
ごめん、やっぱりダメかも。operator[] ではなく at 使うと例外投げるのが仕様だし。
>>607 イテレータ同士の比較とか、C 関数に渡す場合には使えるよね。
/* 要素数 num の int 配列を処理する */
extern "C" void foo(int *data, size_t num);
vector<int> v;
..
foo(&vec[0], vec.size());
610 :
デフォルトの名無しさん :03/01/26 15:55
596です 解決しました。 思いっきり勘違いしてました。最終的に以下のようになりました。 ありがとうございました。 //.h struct mySet { virtual void insert(AnsiString&) = 0; virtual unsigned int getSize(void) = 0; typedef std::set<AnsiString>::iterator iterator; virtual iterator begin(void) = 0; virtual iterator end(void) = 0; }; //.cpp auto_ptr<mySet> pSet; if(RepeatDataCheckBox->Checked)//重複なし { auto_ptr<UniqueSet> instance (new UniqueSet()); pSet = instance; } else //重複あり { auto_ptr<MultiSet> instance (new MultiSet()); pSet = instance; } pSet->insert(tmp); typedef std::set<AnsiString>::iterator iterator; for(iterator it = pSet->begin();it!=pSet->end();++it) { ed->Lines->Add(*it); }
v[n]は*(v.begin()+n)と定義されていて(23.1.1 -12-)、 v.empty()のとき、v.begin()は"past-the-end"っていう値を返すことになってる(23.1 -7-)。 イテレーターiについて、*iが定義されるようなiの値を、"dereferencable"っていう けど、"past-the-end"は"dereferencable"じゃぁない(24.1 -5-)。 ってことで、v.empty()のとき、v[0]は "dereferencable"ではないイテレーターに operator * を適用することになるので、 未定義である。 あとから & つけたところで手遅れだと思われ。
仕様書調べてみたよ。 コンテナ a の operator[](int n) は *(a.begin() + n) と定義されているから、n = 0 のときに *a.begin() (== *a.end()) が許されるか否かが問題。 a.end() は常に past-the-end-value (有効な要素の『次』を指す) イテレータを返し、これ は > 24.1 Iterator requirements > 6. (前略) Values of an iterator i for which the expression *i is defined are called > dereferenceable. The library never assumes that past-the-end values are > dereferenceable ということでデリファレンスしてはいけない。つまり *a.begin() という表記は NG で、 従って &a[0] も NG ってことになる。 ただし、現実には参照はコンパイラ内部ではポインタとして実装されてるから vector<int> v; int& n = &v[0]; int* p = &n; とした場合でも p (n のアドレス) だけ見てる分には問題ない。ただし *p = 1 とか int x = *p といったように、n の値を読み書きすると、一般保護違反で落ちたりメモリ 壊したりする。 ……ってことかね。
一足遅かったか…
>>610 その場合、mySetのデストラクタにvirtualが要る。
MultiSetの実装が謎だ。なんでコンパイルとおるんだ?
絶対解決してないと思うんだが?
>>611 vector<T>::iterator が T* という良くある環境だと問題ないけど、STLport の
デバッグモードみたいに別の型が返ってくる(それをデリファレンスすると T
になる)だと、怒られそうな気がする。
とはいえ微妙に使いにくい仕様だな、これ。
>>609 にあるような C 言語の関
数を呼ぶ場合、どうせ C 関数の方で要素数チェックして 0 なら何もしない、
ってのが普通だし、そっちにチェックを任せたいよな。
ニヤリ
617 :
デフォルトの名無しさん :03/01/26 16:12
610です このようにしましたけど、問題ないようです。 環境はBCB5でWindowsXPです。 //重複なしのコンテナ class UniqueSet : public mySet { std::set<AnsiString> container_; std::set<AnsiString>::iterator itrator_; public: void insert(AnsiString& s) { container_.insert(s); } unsigned int getSize(void){ return container_.size(); } iterator begin(void){ return container_.begin(); } iterator end(void){ return container_.end(); } }; //重複ありのコンテナ class MultiSet : public mySet { std::multiset<AnsiString> container_; std::multiset<AnsiString>::iterator itrator_; public: void insert(AnsiString& s) { container_.insert(s); } unsigned int getSize(void){ return container_.size(); } iterator begin(void){ return container_.begin(); } iterator end(void){ return container_.end(); } };
std::set<int>::iterator f() { return std::multiset<int>::iterator(); } gccでも↑のコードがエラーにならん。 仕様じゃ、ないよな?
>>615 size()==0よりもempty()を使えって話になるんじゃないか?
>>619 それでも
extern "C" void foo(int *data, size_t num);
に対して、これを利用する C++ 側関数は
vector<int> v;
if (!v.empty())
foo(&v[0], v.size());
と場合分けが必要になるよね。
>>620 ↓で問題ないと思う。
inline
void foo( vector<int>& v )
{
  if(!v.empty())
    foo(&v[0],v.size());
}
>>621 俺だったらこんな関数作って使うかな。
templat<class T>
inline T* GetFirstPointer( vector<T>& v )
{
if(v.empty())
return NULL;
else
return &v[0];
}
で、vectorが空でも&v[0]が許される実装で、
かつ効率が気になる場合は
単純に&v[0]を返すように書き換えると。
↑ 誤:templat<class T> 正:template<class T>
>>622 >621のコードを見てなお、>622のコードを使いたくなるのって、どんなとき?
悲しいときー
>>624 ラッパ関数を沢山書くのが面倒な場合だろう。
カブった....。 あとfooが関数オブジェクトだった時や、 fooがvectorのサイズを変更しないことを示したい時にも >622の方を使いたくなるな。
>>627 ということは、末端のコードにGetFirstPointerがばら撒かれるわけか。
  foo(GetFirstPointer(v),v.size());
・・・うーん、あんまり賛成できないなぁ。
>>628 > fooがvectorのサイズを変更しないことを示したい時にも
あー、それあるなぁ。
やっぱりしょうがないかぁ。
>>629 いっそ vector 継承して operator[] だけ再定義したオブジェクトを作るのも
手かもしれんな。
メンバ変数は一切増えないから、デストラクタが virtual でなくとも支障ない
しさ。
>>611-612 でもさ、vector::operator[] って reference を返すじゃん。
てことは、&v[0] は dereference を実行してないと思うんだけど。
まあでも、v.size() == 0 の場合、要素配列を格納するための
有効なバッファがが確保されているかどうかは不明だしねぇ。
やっぱり v.empty() で切り分けるしかないかなぁ。
>>633 > でもさ、vector::operator[] って reference を返すじゃん。
で、規格書読むと reference は「有効なオブジェクトを指さねばならない」と書いてあったり
するわけだ。
> てことは、&v[0] は dereference を実行してないと思うんだけど。
これは &(*v.begin()) と同じ意味なんだが、v.begin() が返すのが単なるポインタではない
場合には、実際に dereference が行われた上で、そのアドレスが計算されることになる。
たいていの処理系だと vector<T>::iterator は T* だから問題ないけど。
>>592 やはり別の理由でした。自作スマートポインタが、変な形式の operator new を持っていたのがいけなかったようです。
(g++ に切り替えてわかったのですが、boost::mem_fn ではなくて、その前のコンテナに突っ込むところでのエラーだったようです。)
それを取り除いて、自作ポインタ用の get_pointer を追加した所、うまくいきました。
ありがとうございました。
それと気がついた事を一つ。 get_pointer は koenig look-up があるので 名前空間 boost に入れなくても よさそうです。
>>636 VC6って演算子じゃない関数は Koenig Lookup 出来ないんじゃなかったっけ。
最近使ってないからはっきり覚えてはいないけど…。
昔、数値計算用に3次元や2次元ベクトルクラス(double型のみ)を自作したりしたんだけど、 最近になってテンプレート化してみたら、同じ型同士は問題なく動くけど 違う型を混ぜると下のように怒られちゃいました。 型をあわせなきゃいけないみたいだけどどうすればいいのでしょう…… borland c++ 5.5でつ vec3<double> a vec3< complex<double> > b,c c=a*b; 『エラー E2094 : * 演算子が使われたがクラス Vec3<complex<double >> では Vec3<double> 型のための定義が存在しない』
vec3<double> + vec3< complex<double> > で、あなたの書いたどのコードが 実行されると期待しているんだ?
>>638 本質的には T から U への型変換が存在する時に、vec<T> から vec<U> への
型変換を認めたい、って話だよね。
それなら、テンプレート化したコピーコンストラクタを作る。vec3 の実装がどうなっ
てるか知らんけど、かりに vec3<T> が private 変数として T 型の配列 v_[3] を
持つと仮定すると、
template <typename T>
class vec3
{
public:
template <typeename U>
vec3(const vec3<U>& other)
: v_(other.v_)
{}
};
ってな感じ。other.v_ (U[3]型) から v_ (T[3] 型) への暗黙の型変換がある場合、
これでよろしく変換できる。
ありがとう。何を調べればよいのかが解らないと自分一人ではどうにもならんので。 配列だと余分なアクセス入るかなと思って、ベクトルの各成分はT v[3]じゃなくてT x,y,zで実装してます。 もっと次数が高ければ当然配列にするだろうけど……あ、配列だったらSTLのvector使えばいいのか。 明日試してみます
テンプレートクラスをstd::ostreamに出力するにはどのように定義すれば いいのでしょうか? コンパイルできるのですがワーニングが出ます。gcc3.2.1(MinGW)です。 template <typename T> class A { T value; public: A(double d = 0) { value = d; } friend std::ostream& operator<<(std::ostream& os, const A<T>& a); }; std::ostream& operator<<(std::ostream& os, const A<double>& a) { os << a.value; return os; } int main() { A<double> a(1.23); std::cout << a << std::endl; }
>>642 なんでそのコンパイラの出力をはぶきやがるんだ?
>>643 すみません、ワーニングをコピペします。
g++.exe "C:\MinGW\Learn\Learn2\template_ostream.cpp" -o "C:\MinGW\Learn\Learn2\template_ostream.exe" -Wall -s -O3 -I"C:\mingw\include" -I"C:\mingw\include\c++" -I"C:\mingw\include" -L"C:\mingw\lib"
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: friend declaration `
std::ostream& operator<<(std::ostream&, const A<T>&)' declares a
non-template function
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: (if this is not what
you intended, make sure the function template has already been declared and
add <> after the function name here) -Wno-non-template-friend disables this
warning
Execution terminated
Compilation successful
>>644 Friend declaration `std::ostream& operator<<(std::ostream&, const A<T>&)'
declares a non-template function.
If this is not what you intended, make sure the function template has
already been declared and add <> after the function name here.
-Wno-non-template-friend disables this warning.
・・・ってなワケだ。あとは好きなように対処しな。
>>645 次のようにしたらコンパイル通りました。ありがとうございました。
ちなみにBCC5.6では通りませんね。
template <typename T>
class A {
T value;
public:
A(double d = 0) {
value = d;
}
friend std::ostream& operator<< <>(std::ostream& os, const A<T>& a);
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const A<T>& a)
{
os << a.value;
return os;
}
int main()
{
A<double> a(1.23);
std::cout << a << std::endl;
}
>>637 なはは…うっかり忘れてました。
その間についに VC++ に別れを告げる決意を固めて、試したのは g++ 上でした。
VC++ では通らないかもしれないです。
>640 無事complex<double> とdouble間の計算が出来ますた。有難う
テンプレート引数の型を文字列リテラルとして取り出したいんですが どうすればいいでしょう。つまりログとりたいんです template<typename T> class Hoge { public: Hoge() { Log::debug("Hoge<T>::Hoge()"); } }; Hoge<int> hoge; で Hoge<int>::Hoge() と表示してほしいんですが・・・
それはconst char*でして、文字列リテラルではないかと・・・ コンパイル時に Hoge<int>::Hoge になって欲しいんです・・・
>>653 無理。
std::string でも使え。
ガビーン あきらめます・・・
"<" と ">" に挟まれた文字列を検索して格納したいのですが。 これで良いでしょうか? { std::string text; std::string __text; std::string::iterator i_first; std::string::iterator i_last; i_first = __text.begin() + __text.find( "<", 0 ) + 1; i_last = __text.begin() + __text.find( ">", 0 ); text.assign( i_first, i_last ); }
>>656 例えばこんなのはどうか。
std::string text;
std::string __text;
std::string::iterator i_first;
std::string::size_type st;
i_first = __text.begin() + __text.find("<") + 1;
st = __text.find(">") - __text.find("<") - 1;
text.assign(i_first, st);
これでもいい。 std::stringはイテレータよりもインデックスで扱った方が 扱いやすいようだ。 std::string text; std::string __text("aaa<abc>def"); std::string::size_type st, st2; st = __text.find("<") + 1; st2 = __text.find(">") - __text.find("<") - 1; text = __text.substr(st, st2);
文字列が"abd>efg<hijklmn"とかだと破綻しねぇか? 全部。
>>659 エラーチェックしてないから。したらしたなりになる。
>>656 boost::regex使えばいいのに。
正規表現で探すのは後に実装する予定でした。 とりあえず抽出だけを考えてます それで、関数を作ってみました。 const std::string Extraction ( const std::string text, const std::string text_open, const std::string text_close ) { std::string output = ""; std::string::size_type position_open = 0; std::string::size_type position_close = 0; std::string::size_type position_target = 0; position_open = text.find( text_open, 0 ); if( position_open == std::string::npos ) return ( const std::string )""; position_close = text.find( text_close, position_open ); if( position_close == std::string::npos ) return ( const std::string )""; position_target = position_open + text_open.length(); output.assign( text, position_target, position_close - position_target ); return ( const std::string )output; }
使用してみました std::string t; t = Extraction( "a<b<c<d", "<", ">" ); // 無 t = Extraction( "a<b<c>d", "<", ">" ); // b<c t = Extraction( "a<b>c<d", "<", ">" ); // b t = Extraction( "a<b>c>d", "<", ">" ); // b t = Extraction( "a>b<c<d", "<", ">" ); // 無 t = Extraction( "a>b<c>d", "<", ">" ); // c t = Extraction( "a>b>c<d", "<", ">" ); // 無 t = Extraction( "a>b>c>d", "<", ">" ); // 無 STL 初心者なもので、色々と不具合があるかもしれません。 みなさんどうもありがとうございました
>>662 これではいかぬか
const std::string Extraction
(const std::string& text, const std::string& text_open, const std::string& text_close)
{
std::string::size_type position_open = text.find(text_open), position_close, position_target;
if (
position_open == std::string::npos
|| (position_close = text.find(text_close, position_open)) == std::string::npos
|| (position_target = position_open + text_open.length()) > position_close
)
return std::string();
else
return std::string(text, position_target, position_close - position_target);
}
boost::shared_ptrのような非進入型参照カウンタを使ったスマートポインタって スマートポインタ同士の直接代入はできるけど、 スマートポインタから生ポインタを取り出して、それを別のスマートポインタに入れると参照カウントの二重管理になって悲惨な結末になるんですよね。 んで、普段は可能な限りスマートポインタを使うことでどうにかなるんですけど、 一ヶ所だけ絶対にスマートポインタが使えないところがあって、 つまり this ポインタなんですけどね。 boost::shared_ptr< MyType > MyType::GetObject( std::string name ) { return boost::shared_ptr< MyType >( this->name==name ? this : new MyType( name ) ); } みたいな必要があったとき、皆さんならどうしますか? 私はもうぜんぜん思いつかないんで進入型に切り替えるしかないかなぁとか思ってますが。
その場合MyTypeを管理している上位クラスが全部責任を持つ構造にする。
667 :
デフォルトの名無しさん :03/01/31 23:37
STLportのhashって使ってみられた方いらっしゃいます?
>>667 hash_map ではなくて、ハッシュ値を計算する hash の方? 使った事はあるけど。
>>668 hashのアルゴリズムは処理系依存なんですよね。
どういう仕組みで発生しているのか興味があります。
>>669 > hashのアルゴリズムは処理系依存なんですよね。
STLport の hash の話をしてるなら、処理系非依存だが。stl/_hash_fun.h に
書いてあるから読んでみ。
ちなみにテンプレートクラスとして定義されているので、ユーザ定義クラスに対する
ハッシュ値は、自分で specialization しないと計算できない。
>>670 inline size_t __stl_hash_string(const char* __s)
{
_STLP_FIX_LITERAL_BUG(__s)
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5*__h + *__s;
return size_t(__h);
}
これでしょうか。割と簡単な事してるんですね。ありがとうございました。
ファイルの内容を表示するプログラムを作ってみたのですが、 改行を表示してくれません。どこを直せば良いでしょうか。 int main() { std::ifstream ifs("copy1.cpp"); std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout)); }
>>673 std::istream_iterator<type>(i)は、i >> t を内部で実行しているため、
ホワイトスペース文字はスキップされて読み込まれない。
>>674 ありがとうございます♪
意外でした。std::getlineか何かで読み込んでみることにします。
>>675 std::noskipwsをストリームに食わせてやれば、ホワイトスペース
文字も読み込める。
int main()
{
std::ifstream ifs("copy1.cpp");
ifs >> std::noskipws;
std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout));
}
> ifs >> std::noskipws; 何か、「食わせてる」 って気がしないよな。
ちなみにそういう場合は[io]streambuf_iteratorを使ったほうが速いぞ、と。
某所で見かけた静的配列の長さを調べるコード。ちょっと感動した。 template< typename T, size_t N > inline size_t length_of( T(&)[N] ) throw(){ return N; } それを参考にした、静的配列の最後の要素を得るコード template< typename T, size_t N > inline T& last_element_of( T(&array)[N] ) throw() { return array[N-1]; }
なるほどこれなら単純で良いね。 int main() { std::ifstream ifs("copy1.cpp"); std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout)); }
STLportって何がいいの?ラインセンスもアレだし。
682 :
デフォルトの名無しさん :03/02/03 12:03
>>679 ちなみに某所ってどこよ?他にもお宝眠ってたりせんかの?
>>682 tp://www.issei.org/diary/ にて。
>>683 そーだったのか…
>>684 なるほろthx!
>>683 まぁまぁそう言わんと。知らん人間にとっては新しくなくても十分面白かったんで。
>>684 その日記の元ネタは cuj web site の記事。URL を忘れたので元記事へのリンクを
張らなかったんだが、google に掛け合って見つけてきたよ。制限事項に関しても詳
しく書いてあるから、ざっと読んでおくと良いと思いかと。
http://www.cuj.com/articles/1999/9902/9902h/9902h.htm?topic=articles これに関連した小ネタだと、std::for_each のような一定範囲を扱うアルゴリズムに
次のような多重定義をしておくってのもある。for_each や find_if は、コンテナ全部
に適用したいケースが多いから。
template <class T, class TFunc>
inline TFunc for_each(T& col, TFunc f)
{
return std::for_each(col.begin(), col.end(), f);
}
template <class T, int N, class TFunc>
inline TFunc for_each(T (&ary)[N], TFunc f)
{
return std::for_each(&ary[0], &ary[N], f);
}
template <class T, int N, class TFunc>
inline TFunc for_each(T const (&ary)[N], TFunc f)
{
return std::for_each(&ary[0], &ary[N], f);
}
687 :
デフォルトの名無しさん :03/02/03 23:42
lokiのSmartPtrを使ってるひとはいますか? あれがもっとも汎用的でいいと思うのですが なんでboostには含まれないのかな?
>>687 つかってまつ。gcc 2,95のバグに悩まされました。
>>687 いま、ちょうどboostのMLでLokiの人含めて色々議論してるようだから読んでみれば?
>>687 boost-mlでなんか今 auto_ptr みたいな挙動をどーするか
議論してるよ。boostに取り込まれる予定なはず。いつかは知らんけど。
ぐはぁ、かぶった。逝ってきまふ・・・
>>691 逝かんで良いから、議論の流れをザクッと要約してくれると嬉しい。
>>692 無理でふ。サラッと見ながら
「あー、なんかモメてるっぽいなぁ」
程度にしか読んでいないので・・・
「結論出たら結論だけ見ればいいや」
と思ってるんであんま(全然)流れ追ってないんですわ。
ちなみに今は配列のサポートでまた何やら議論してるみたい。
これも別にマトモに追ってないんですけど。
>>680 単純がいいなら、こっちにしとけば?
main()
{
std::ifstream ifs("copy1.cpp");
std::cout << ifs.rdbuf();
}
それってどれくらいメモリ食うの?
>>699 なんで「メモリ食う」なんて思ったんだ?
ファイルの読み取りバッファと標準出力の
書き込みバッファくらいしか思いつかないんだが。
>>700 いや、内部的に何が起こるのかなと思って。
>>701 「内部的」なことは当然わからんが、
1文字ずつ読んだ場合に比べて余分に
メモリを必要とする理由はなにもない。
703 :
デフォルトの名無しさん :03/02/05 15:24
低レベルな質問で申し訳ないですが, binary_function<Arg1, Arg2, RetVal>にはoperator() 定義されてないんでしょうか? cout << plus<int>()(2,3) << endl; は上手くいくのに, binary_function<int, int, int> fn = plus<int>(); cout << fn(2, 3) << endl; は上手くいきません.
>>703 定義されてない。
operator()は仮想関数じゃないよ。
では,関数オブジェクトを引数として渡したい場合は, 引数の型は何にしたらいいんでしょうか?
>>705 ふつうはテンプレートの型引数だな。
template<typename BinaryFunction>
void f(BinaryFunction fn);
<algorithm>以下の関数でもそうしてましたが, テンプレートで取り込もうとすると, 色々と面倒な事起こりませんか? 出来れば,引数として取り込みたいのです.
すいません.↑意味不明でしたね. 様はtemplateは使わずに, void f(binary_function<int, int, int> fn); みたいな感じで使いたいのです. binary_functionはlessやらplusやらの基底クラスらしいですが, 共通に使われるであろうoperator()を仮想関数として定義 してないんじゃ使えないですね. 引数としてこのクラスの関数オブジェクトを読み込む場合, この代わりに何を基底クラスとして使うべきなのでしょうか?
>>709 templateを使って定義すると,
ソースコードをいちいちincludeしないといけなくなりませんか?
>>709 そんな方法はない。お前はbinary_functionの存在理由を大幅に誤解している。
>>709 そうなると、基底クラスじゃぁないが、boost::functionなんだろうなぁ。
>>709 binary_functionはtypedef導入用のテンプレートであって、
多態で使うことを目的としたものじゃない。
> void f(binary_function<int, int, int> fn);
何故templateにしないでこうしたいのかがよく
わからんが、とりあえず boost::function 使え。
>>709 binary_function は引数、戻り値の型を class 内の typedef として定義するための
クラス。それ自身はなんの機能も持たない。
Generic Programming あたりを読んでお勉強するのが良いと思われ。
BCCで、 テンプレート引数の整数はunigned int ではだめで、特別化がおきず、intにしなくてはいけません。 これってC++の仕様ででしょうか?整数引数単独のテンプレはOK。 #include<iostream> template<class T,unsigned int Sz> struct vector{ public: vector(){std::cout << "Standard" <<std::endl;} }; template<class T> struct vector<T,3>{ public: vector(){std::cout << "Special" <<std::endl;} }; int main(){ vector<double,1> v1;//Standard vector<double,3> v3;//Specialになってほしいが・・・ return 0; }
>>716 BCC5.6.2だとちゃんとSpecialになるよ。
>>717 お、そうですか・・・。BCC5.5のバグなんですね。ありがとうございます。
VC++7.0 で、以下の式が正しく通るんだけど… // ↓LokiPort for VC++7.0 Loki::SmartPtrDef<MyClass>::type sp( new MyClass ); sp[ 2 ]; 犯人は特定できたけど、この仕様のおかげで、 自作の添え字演算子を持つポリシーが使えないじゃないかっ!
>>719 音無しくboost::shared_arrayにするよろし
ヤス
>>722 いつのネタだよ。
ポートピア連即殺人事件の中の人も大変だな。
>>719 operator Tester*()
こいつのおかげで、operator[] が曖昧だといわれてしまう。
>>723 中の人な(ry
ザクの犯人はシャア
templateの型推測のアルゴリズムが今ひとつわかりにくかったので 良書を探していたら、C++Primerが目に止まった。 この本はC++初心者用だからと今まで目もくれなかったが、今日 何気に立ち止まって読んでみると、templateについてじつに詳しく 書いてある。これだけでも買う価値があると思い、速攻レジへ。 本の厚さに圧倒されつつも、読んでいます。アルゴリズムについて も相当詳しい解説があります。でもアルゴリズムは一通りやった んだけどな。
729 :
デフォルトの名無しさん :03/02/08 00:14
treeコンテナ でおすすめなものないでしょうか?
>>729 set とか map とか、内部実装的には tree になってるよ。
ちなみに、STL で使われてる平衡木アルゴリズムは二色木(red black tree)。
732 :
デフォルトの名無しさん :03/02/08 02:36
>>730 バランス木または多分木のコンテナが欲しいです。
ゲームの探索に使おうと思ってます。
>>732 要するに、そのゲームに特化した最適な構造の木を使いたいってこと?
そんな特定用途向けのライブラリ、早々転がってないぞ。
とりあえず、STL ので我慢して作って、
パフォーマンス的にどうしても必要になったら改めて自作しろ。
2つの型が同じかどうか判定することってできるでしょうか template<typename A, typename B> bool IsSameType(); いろいろ考えましたが思いつきませんでした・・・
>>731 std::map をどうやって「木として」使うんだ?
>>729 平衡木なら
http://www.essemage.com/aapl/ とかが有名どころではなかろうか。
多分木はあんまり見たこと無いなぁ。
>>734 template<typename A, typename B> struct ist { enum{ val = 0 }; };
template<typename A> struct ist<A,A> { enum{ val = 1 }; };
template<typename A, typename B>
bool IsSameType() { return ist<A,B>::val; }
class A1; class A2; ... class B { private: A1 a1; A2 a2; ... public: }; の時にa1、a2に[]を使ってアクセスする方法はないでしょうか?
#define private public
あ、違った。失礼。 まぁ、operator[]でも定義しなさいってこった。
A1,A2,・・・がA_Baseから派生していて、a1,a2が配列要素になっていたら [ ]を定義できるのですが、この場合どうやったらいいか分かりません。 また上記の場合派生して加えた関数にアクセス出来ません。templateを使って旨く出来ないでしょうか?
ん? B::operator[] をテキトーに定義してやるんじゃマズいの? なんか良く意味が分かんないんだけど。
>>737 B b; があって、
b[0]がa1、b[1]がa2を返すとか、そういう事かい?
switchでべた書きでは無くて何か巧くできないものかと思いまして。
>>742 そんな感じです。
B b;
で、b[0].func(hoge) とか出来ない物かと。
>>744 A1とA2が継承関係にでもないと、一つの[]でA1とA2両方返すのは
難しくないかい?
なんかすっきりせんな。 struct A1 { virtual void func() { std::cout << "A1" << std::endl; } }; struct A2 : public A1 { void func() { std::cout << "A2" << std::endl; } }; struct B { A1 a1; A2 a2; A1* operator[](int i) { if (i == 0) return &a1; else return &a2; } }; int main() { B b; b[0]->func(); b[1]->func(); }
あぁ、そっかそっか。
>>744 で、[]の引数はやっぱコンパイルタイムには決まらんの?
決まるんなら boost::tuple みたいな事すれば
b.get<0>().func(hoge)
なら出来る・・・かな?
friendとtemplateの特殊化を使って実装しようかと試みたが、[]は メンバ関数でないとだめみたいだしなあ。friend使えたら何とか なったかもしれんのだが。
だめだこれでも継承関係しか受け付けない。 struct A1 { virtual void func() { std::cout << "A1" << std::endl; } }; struct A2 : public A1 { void func() { std::cout << "A2" << std::endl; } }; struct B { A1 a1; A2 a2; A1& operator[](int i) { if (i == 0) return a1; else return a2; } }; int main() { B b; b[0].func(); b[1].func(); }
可能だとしても、そんなオーバーロードは認めたくないね。
皆さんありがとうございます。難しいのですね。
>>747 さんの方法も含めて考えてみます。
出来るだけpublicにはしないように頑張っているのですが、初心者には中々難しいです。
struct A1 { void func() { std::cout << "A1" << std::endl; } }; struct A2 { void func() { std::cout << "A2" << std::endl; } }; struct B { A1 a1; A2 a2; void* operator[](int i) { if (i == 0) return &a1; else return &a2; } }; int main() { B b; reinterpret_cast<A1*>(b[0])->func(); reinterpret_cast<A2*>(b[1])->func(); }
派生クラスの関数呼び出すんなら、配列(的)にする意味あるの?
>>753 B b[100];
としたいので、b[1][1].func(hoge)って呼べた方が楽だなぁと思ったのです。
>>752 ありがとうございます。参考にさせて頂きます。
>>754 > としたいので、b[1][1].func(hoge)って呼べた方が楽だなぁと思ったのです。
激しく読みにくいコードのような気がするが…
面倒でも、素直に「役割」を反映したメソッドを書いて deletate した方が
良いと思うぞ。
>>734 > 2つの型が同じかどうか判定することってできるでしょうか
boostの、<boost/type_traits.hpp>をインクルードして、
boost::is_same<T, U>::value
でいけるようだが、中身を見ても何をしているのか解らなかった・・・。
>>730-736 結局、色々やるには自分で作った方がいいという結論になったのですが、
上記の物は参考にはなりました。
ありがとうございました。
//構造的にはこんな感じ
template <typename _Elem> class tree
{
tree *parent;
list<tree*> m_child;
_Elem m_element;
};
759 :
デフォルトの名無しさん :03/02/10 10:48
spirit & phoenix ホントにキタ━━━━━━(゚∀゚)━━━━━━ !!!!!
760 :
デフォルトの名無しさん :03/02/10 18:11
スレ違いかもしれんけど、いい知恵を貸してください。 COMなんかで使用する BSTR は ATLインターナル等を読む限り、 「長さをプレフィックスとするOLECHAR型の文字列」だそうです。 ~~~~~~~~~~~~~~~~~~~~~~~~~~ で、これを std::basic_string で表現したいと思い、 char_traits をいじり始めたのですが、 「長さをプレフィックスとする」の部分で躓きました。 このような長さを先頭にもつ文字列を basic_string で表現する うまい手段があったら教えてください。
>>760 basic_stringで表現するより、
別のクラスにしてbasic_stringと相互?変換できるようにするほうが楽じゃないの?
760はマルチ
763 :
デフォルトの名無しさん :03/02/10 21:28
ここでシェルスクリプトのこと聞いてもいいでつか? それとももっと適した板があるなら教えてくだたい
>>763 シェルスクリプトならUNIX板とかLinux板とかでないかね
>>760 どっちみち、一般のヒープ管理関数じゃなくてSysAllocStringで確保しなきゃいけないわけだし、
プレフィックス部分はポイントされている番地より「前」に存在するわけだし、
いじるならchar_traitsじゃなくてallocatorのほうではないか。
char_traitsはそのままstd::char_traits<wchar_t>でいい気がする。
void wfstream::open (const char* __s, ios_base::openmode __mod = ios_base::in) ファイル名が、なぜ wchar_t でなく char なのでしょうか?
767 :
デフォルトの名無しさん :03/02/12 20:36
VC7で以下が通らないのはVC7のバグ?それとも俺の思い違い? #include <iostream> #include <memory> class A { public: void Print(void){ std::cout << "OK" << std::endl; } }; int main() { std::auto_ptr< A > ptr( new A() ); void (A::*method)(void) = A::Print; (ptr->*method)(); // ここや return 0; }
ptr->* って、std::auto_ptr<A>型についてのメンバ関数へのポインタを 探すことにならんか?
>>767 ptrはA型へのポインタだから、当然Aの中にmethodというメンバ
がないとエラーになる。
struct A {
int i;
}
std::auto_ptr<A> ptr(new A);
int j;
ptr->j;
としているのと極端に言えば同じ。
A* a; (a->*method)(); としたら通るね。ということは、std::auto_ptrの->演算子の多重定義 の問題なのだろう。 ->の先がメンバー関数へのポインタだった場合、正常に解釈して くれないのでは。
どうか見捨てないで下さい
773 :
デフォルトの名無しさん :03/02/12 21:34
((*ptr).*method)() にしれ
>>767 auto_ptr<> には operator->* というメンバ関数はないので
どのコンパイラでも無理だ。
あっそうか!->という演算子ではなくて->*という演算子なのだね。 ((*ptr).*method)() が通るという事は、.*は定義されているのかな。
>>775 (*ptr)の時点で A* になってる
あ、ちがうか、A&か。
>>776 >>777 なるほどよく理解できました。
そしたら、((*ptr.get()).*method)();が通る理由も理解できます。
>>773 神
ってゆーかその手に気付かなかった自分が恥ずかしいよ。
->が定義されてるなら->*も自動だと思ったんだけどそうじゃなかったんだな。
ためしに->*を定義してみたらなかなか面白いことになったけどいまいち使いどころがわかんね。
->* って定義できたっけ?
でも逆に .* は定義できないんだよね。 ->*が定義できるのだから、今度の新しい標準C++はstd::auto_ptrにも 定義して欲しいものだ。
operator->* をユーザー定義して普通の ->* と同じ動作をするものを 作ろうと思ったら、boost::bind 完全再生産、くらいのレベルで大変なんだけど、 なんであんな規格なんだろう。
オーバーロードできない演算子って、 . .* :: ?: sizeof # ## で全部?
スマートポインタが->*をサポートするには何を返せばいいんだ? ->が返すのは生ポインタだよね。
>>785 こんな感じかと
#include <iostream>
#include <functional>
class A
{
public:
int b;
void hoge( int v ){ std::cout << b << v << std::endl; }
public:
template< typename type >
type& operator ->*( type A::*p ){ return this->*p; }
template< typename type >
std::binder1st< std::mem_fun1_t< type, A, int > >
operator ->*( type (A::*p)( int ) ){ return std::bind1st( std::mem_fun1( p ), this ); }
};
int main()
{
A a;
int A::* pb = &A::b;
a->*pb = 10;
void (A::*phoge)( int ) = A::hoge;
(a->*phoge)( 20 );
}
>>784 throw 演算子もできないような気もするが……できるならサンプルプリーズ
>>787 にゃるほど。少し分かりました。thx.
>>787 凄すぎ。このコードを理解するように努めてみます。
>>786 忘れてました。ども。
そういえば、std::XXX_cast<> 達はキャスト「演算子」なのですかね。
だとしたらオーバーロードできない、でいいと思うけど。
>>788 手元のプログラミング言語C++ 第2版では、throw は演算子じゃなくて式(の一部)のようです。
第3版がほすぃ・・・。
792 :
デフォルトの名無しさん :03/02/15 07:19
listのeraseで自分のコンテナ以外の反復子を削除できるようなのですが、 この使用は抑止した方がいいのでしょうか? #include<list> #include<iostream> #include<string> #include<vector> using namespace std; int main() { list< vector<string> > a,a2; vector<string > s,s2; s.push_back("111"); s2.push_back("222"); a.push_back(s); a2.push_back(s2); a.erase(a2.begin()); //aのeraseでa2の反復子を削除する。 //list<T>::eraseのソースをみると //_Mysize--;となっているが、 //_Mysize=size();としないと矛盾しないか?(debbugerのsizeも0,1になってる) cout << "a size:" << (*(a.begin())).size() << std::endl; cout << "a2 size:" << (*(a2.begin())).size() << std::endl;//a2の要素は削除されてる //これはbegin()とend()から計算してるから大丈夫。 cout << "*a.begin():" << *(*(a.begin())).begin() << std::endl;//111 }
>>792 実装的にその方が楽なんよ。
STLは計算効率至上主義だからそういう風になってるんだと思われ。
ほんとはそういうまねは出来ない方がいい。
>>793 ちと勘違いしてたんで、修正した。
サイズ等の状態数を管理するのって危険が伴うのにそれを完全に排除してない
方が悪い気がするんだけど。
//上と同じ
int main()
{
list< vector<string> > a,a2;
vector<string > s,s2;
s.push_back("111");
s2.push_back("222");
a.push_back(s);
a2.push_back(s2);
a.erase(a2.begin()); //aのeraseでa2の反復子を削除する。
cout << "aのeraseでa2の先頭の反復子を削除する" << std::endl;
cout << "a.size() :" << a.size() << std::endl; // VC 0 ,GCC 1
cout << "a2.size():" << a2.size() << std::endl; // VC 1 ,GCC 0
cout << "(*a::begin()).size()) :" << (*(a.begin())).size() << std::endl; // VC 1 ,GCC 0
cout << "(*a2::begin()).size()):" << (*(a2.begin())).size() << std::endl; // VC 1 ,GCC 0
cout << "*(*(a.begin())).begin() :" << *(*(a.begin())).begin() << std::endl;//111
//cout << "*(*(a2.begin())).begin():" << *(*(a2.begin())).begin() << std::endl;//
}
>>794 よくみたらミスってました...。
cout << "(*a::begin()).size()) :" << (*(a.begin())).size() << std::endl; // VC 1 ,GCC 1
cout << "(*a2::begin()).size()):" << (*(a2.begin())).size() << std::endl; // VC 0 ,GCC 0
であってると思います。
>>794 Sequence::erase の Precondition を破っているので、
未定義動作でしょうがないと思われ。
797 :
デフォルトの名無しさん :03/02/16 02:30
STLport 使ってて(iostreamは使用せず) ICU使いたいんですけど STLportのスタティックライブラリにする必要あります? 経験者の方教えてください。
>>796 同じ型のコンテナ内の反復子を矛盾なく削除できる関数として
機能したほうがいいと思うんだけど。
その代わり、多少パフォーマンスは下がってしまうか。
コンテナが反復子の状態数を保存してるときは
反復子を操作(削除)するときに
管理しているコンテナに通知して処理するほうが望ましい結果が得られる。
799 :
デフォルトの名無しさん :03/02/16 09:03
Boostsを使いたいのですがどこか日本語で詳しく解説してあるサイトか本はありませんか? あったら教えてください。
>>798 iteratorは基本的に自分が属するContainerがどれであるかを知らないし、
Containerは基本的に自分の上のiteratorがどこかに存在しているかどうかを
知らないし、
algorithmは自分が操作する対象がどんなsequenceであるかを知らない…
という形にすることで可能な限り一般性を高める、というのが
STLの方向性だと思うので、↓の是非は別にして、
> コンテナが反復子の状態数を保存してるときは
> 反復子を操作(削除)するときに
> 管理しているコンテナに通知して処理するほうが望ましい結果が得られる。
これはSTLに求める性質としてはお門違いではないかと。
>>800 , 801
ありがとうございます。
自分でさがせ、殺すぞ、とか言われるかと思いましたがやさしいですね。
>>802 一般的な反復子にはもちろん同意だが、
コンテナ内のtypedef(または定義)されたiteratorを
削除するときは違う。
a.insert(a2.begin()) -> は問題ない
a.erase(a2.begin()) -> a2側に通知が必要
STLの性質を求めてるんじゃなくて、
結果が正しくなることを求めてる。
使い方が間違ってるのに結果が正しくなるのは無理だと思われ
>>804 自分で勝手に自分がどのコンテナオブジェクトに属しているかを知っている
イテレ−タを使ってアクセスされるリストクラスでも作って使っとけアホ。
とりあえず話を
>>792 に一旦戻すと、
> listのeraseで自分のコンテナ以外の反復子を削除できるようなのですが、
自分のコンテナ以外の反復子を指す要素は削除「できない」。実装によっては
たまたま削除されてしまうかもしれないが、その辺りの動作は未定義。
それをふまえて。
> a.insert(a2.begin()) -> は問題ない
a.insert(a2.begin, value) か? a.erase(a2.begin()) と同じ程度には問題あるだろう。
> 結果が正しくなることを求めてる。
sqrt( "弐" ) とやったら "1.41421356" と返すのが正しい結果だ、
と主張してそれを求めてるのに等しいことは自覚してるか?
無論、sqrt( "弐" ) と同じでコンパイルエラーになるとか、最悪でも
実行時エラーになったら嬉しいのは確かだし、(だからSTLPortの
Debug版とかはかなり重宝されている。) staticメンバ関数を使って
list<T>::erase(a2.begin()) と書けるiterator/container はそれなりに便利だろう。
が、それはSTLの範疇じゃない。
×反復子を指す要素 ○反復子の指す要素
809 :
デフォルトの名無しさん :03/02/16 14:07
810 :
デフォルトの名無しさん :03/02/16 19:14
STL含んでいるObjectを、Exe <-> Dll 間で使用していると 保護違反が発生するのですが、STLはExeをまたがって使用できないのですか? 環境は .Net STLはMS製です。
>>810 MSの作るのDLL/EXEは、MSVCRT.DLLを使わない限り、ヒープを個別に
持つことになる。片方でnew/mallocしたものを他方でdelete/freeすると
当然おかしなことになる。
MSVCRT.DLLを使うか、またがってnew/deleteをしないよう
気をつけるしかない。
812 :
デフォルトの名無しさん :03/02/16 19:54
重複項を省くためにsetを使っているですが、 list<N>::iteratorの比較をしたい場合には、どのようにしたら良いのでしょう? list<N>::iterator il; // Nは適当なクラス set<list<N>::iterator> lset; lset.insert(il); // 必要なilを適宜追加する。ここでの重複を省きたい。 (とりあえずコンパイル通すために)以下のようにiteratorの比較をしています bool operator < (const std::list<N>::iterator lhs, const std::list<N>::iterator rhs) { return &(*lhs) < &(*rhs); } g++(2.96〜3.2)では通るのですが、Intel Compiler(icc)では、 # error: no operator "<" matches these operands # operand types are: const std::list<N, std::allocator<N>>::iterator # < const std::list<N, std::allocator<N>>::iterator とはじかれてしまいます。 どうすれば解決するかご指摘いただけないでしょうか?
template< typename Iterator > struct compare_dereferenced_address : std::binary_function< bool , Iterator , Iterator > {   bool operator () const ( const Iterator& lhs , const Iterator& rhs )   { return &(*lhs) < &(*rhs); } }; set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset; Interl Compiler 持ってないから、実験はできないけど、 とりあえず行儀よくしてやったら治らないかね?
>>811 レスありがとうごさいます。
>またがってnew/deleteをしな気をつけるしかない。
この修正してきます
>813 治りました。ありがとうございます。 binary_functionにあまり馴染んでないせいか(必要にかられて本を調べる程度) set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset; こんな風に宣言できることすら思いつきませんでした。
816 :
デフォルトの名無しさん :03/02/16 21:31
boostとstdの function の Resultの位置は逆になってたような...。
コンパイルが通るだけに、恐ろしい罠だのぅ。
解決したつもりになっていたのですが、、、 set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset; とすると確かに通るのですが、挙動不審です。 どうも元の set<list<N>::iterator> との型の互換で失敗しているようです。 この辺のデバッグが非常に面倒なプログラムなので、 できれば素の、set<list<N>::iterator>のまま通したいところです。切実に、、 せっかく bool operator < (const std::list<N, std::allocator<N> >::iterator lhs, const std::list<N, std::allocator<N> >::iterator rhs) { return &(*lhs) < &(*rhs); } と、operator用意しているのに、何で使ってくれへんの? と悲鳴をあげつつ 以下がエラーメッセージ全文となります。うざったくてすんません。 どうか、もちょっとだけアドバイスを下さいませ。 /opt/intel/compiler70/ia32/include/functional(134): error: no operator "<" matches these operands operand types are: const std::list<N, std::allocator<N>>::iterator < const std::list<N, std::allocator<N>>::iterator return (_Left < _Right); ^ detected during: instantiation of "bool std::less<_Ty>::operator() (const _Ty &, const_Ty &) const [with _Ty=std::list<N, std::allocator<N>>::iterator]" at line 471 of "/opt/intel/compiler70/ia32/include/xtree" instantiation of "std::_Tree<_Traits>::_Pairib std::_Tree<_Traits>::insert(const std::_Tree<_Traits>::value_type &) [with _Traits=std::_Tset_traits<std::list<N, std::allocator<N>>::iterator, std::less<std::list<N, std::allocator<N>>::iterator>, std::allocator<std::list<N, std::allocator<N>>::iterator>, false>]"
> set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset; > とすると確かに通るのですが、挙動不審です。 > どうも元の set<list<N>::iterator> との型の互換で失敗しているようです。 失敗じゃネェよ。そいつらは違う型だ。 set<list<N>::iterator>を使ってたところで全部同じ型を使うように汁。
>>818 多分
template<typename T> void function( tmpl<T> t ) { ... }
という定義があれば tmpl<T> t; function(t); で見つけられるけど、
template<typename T> void function( tmpl<T>::type t ) { ... }
では tmpl<T>::type t; function(t); では見つからないはず。
# スマートポインタを ptr<T>::shared とか ptr<T>::auto とか ptr<T>::locked
# とか書きたいけど書けねぇなぁ、という議論で見かけた気がする。
ので素直に、
1: set<list<N>::iterator> を(名前は適切なものをつければいいが) set_of_N_iter に置換
2: typedef set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> >
set_of_N_iter;
しとけ。
あるいは、iteratorの比較関数をtemplateにしないで
bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
と一個一個書いていけばいいような気もするが。
>819 >set<list<N>::iterator>を使ってたところで全部同じ型を使うように汁。 ごもっともです。 それでうまくいかなかったのは、やはり元のコードがbuggyだったせいかと。 >820 >bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... } >と一個一個書いていけばいいような気もするが。 これはどうも無理でした。 >では tmpl<T>::type t; function(t); では見つからないはず。 つまり、見つけられた(コンパイラ)の方がたまたまだったというわけでしょうか…… >ので素直に、 (中略) しとけ。 はい、そうしますわ。こつこつバグ治します。
>>821 素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
比較できたっけ?
==か!=でしか比較できなかったような気がするんだが。
それから、std::setの比較基準なんだけど、 1.std::set<Elem, Op> 2.std::set c(Op) のどちらかでしか比較基準は指定できないよ。これを使わず operator< を定義しても使ってはくれない。
>>823-824 > 素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
> 比較できたっけ?
だから812氏は苦労して { return &(*lhs) < &(*rhs); } なんて奇怪な
比較関数を作ってるんじゃねーの?
> のどちらかでしか比較基準は指定できないよ。これを使わず
> operator< を定義しても使ってはくれない。
set<T> とやったら比較ポリシーは std::less<T> になるから、
operator < が呼ばれる。つーか、キミ、勉強し直せ。
>>821 追実験。。
> >bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
> >と一個一個書いていけばいいような気もするが。
Comeau のオンラインコンパイラで試してみたら、
namespace std {
bool operator<( const list<int>::iterator& i, const list<int>::iterator& j ) { ... }
}
とstdの中に突っ込んで置いたら一応コンパイルは通ったぞい。
猛烈に行儀が悪いので、止めた方が無難だが。
それがランダムアクセスイテレータなら大小関係の比較できる。
>826 通りました! まさにピンポイントなアドバイス! >猛烈に行儀が悪いので、止めた方が無難だが。 よそのコンパイラでお行儀悪くするためにはコツが必要なのですね。 ありがとうございます。 >827 なるほど。const list<N>::iteratorではなく、const vector<N>::iteratorの場合、 operator < を作る必要がなかったので不思議に思っていました。 勉強になりました。
829 :
デフォルトの名無しさん :03/02/19 01:45
boostやSTLportのtype_traitsをユーザー定義型で特殊化するサンプルってありますか?
830 :
デフォルトの名無しさん :03/02/21 05:05
次期vsはC++標準準拠度があがるみたいだけど もうstlport使わなくてよくなるかな
もしかしたらVCもSTLport標準装備だったりして。
STLの実装がいくつもあってもあんまりいいことないよね
そろそろSTL開発会社も自然淘汰の時期だ。
managed C++ が多重継承できませんから。 stl なんか使いませんとも。
835 :
デフォルトの名無しさん :03/02/21 14:25
2つのvectorがあって、1方にだけ含まれる要素を 抜き出すにはどうすればよいですか? 片方に含まれる、両方に含まれる、どちらにも含まれる、で 処理を分けるようなこともしたいです。
836 :
デフォルトの名無しさん :03/02/21 14:35
>>835 ソート済みなら
std::set_union()
std::set_intersection()
std::set_defference()
が使えるかと。
>>835 片方にのみ含まれる - std::set_difference()
どちらにも含まれる - std::set_intersection()
両方の集合の和 - std::set_union()
但しこれらのアルゴリズムは必ず std::vectorを sort() してから
呼び出さなければならない。
ケコーン(w
親切度低いぶんだけ早かったな俺(w
簡素な即レスと、丁寧な遅レスはどっちがより親切だろう?
843 :
デフォルトの名無しさん :03/02/25 22:32
低レベルな質問で恐縮ですが VC7にSTLportを導入した、つもりなんですが どうも上手くいっていないみたいです。 ちゃんとSTLportが使われているかチェックする方法はないですか? インクルードディレクトリを切り替えてlistの性能比較とかしても差がないし、 iostreamもSTLport版を使うようにし他場合、 #define _STLP_USE_DYNAMIC_LIB してできた実行ファイルを Dependency Walkerで調べたらstlport_vc745.dllが表示されると 思っていたんですが、表示されませんでした。思い違いでしょうか? インストールが上手くいっていないだけですか?
>>843 std の変わりに _STL ネームスペースを使って正常にコンパイル
できるかどうかチェックする。
>>844 コンパイルできませんでした(泣
導入からやり直します。ありがとうございました。
>>845 SGI系のアダプタである _STL::compose1 とか _STL::compose2 が
コンパイルできるか確かめてみる方法もあるよ。
847 :
デフォルトの名無しさん :03/02/26 00:00
std::vector x(10); for(int i=0;i<10;++i) cin >> x[i]; を for で回さないでなんか algorithm 使って出来ないですかね? std::vector x(10); std::transform(x.begin(), x.end(), x.begin(), bind1st(std::mem_fun(&std::istream::operator>>), &std::cin)); で逝けるかなぁと思ったんですけど、 no matching function for call to `mem_fun(<unknown type>)' と gcc-3.2.1 に言われてしまって… まぁ完全に趣味なんで別に for で回せばいいんですけどね。
>>847 #include <iterator>
std::copy_n( std::istream_iterator<T>(cin), x.size(), x.begin() );
って、copy_n ってもしかしたらSGI拡張だったかも…。
>>848 やってみたけど11個数字を入れないと終了しないよ。
STLport。
>>847 多分それがだめなのは、operator>>の戻り値型がstd::istreamだから
だろう。
>>847 ファンクタを作ったらだめかい?
template <typename T>
struct input {
T operator()(T& t) {
std::cin >> t;
}
};
int main()
{
std::vector<int> x(10);
std::transform(x.begin(), x.end(), x.begin(), input<int>());
std::copy(x.begin(), x.end(), std::ostream_iterator<int>(std::cout, " "));
}
>>850 おー、ほんとだ。istream_iterator って operator* じゃなくて
コンストラクタと operator++ のタイミングで読まれるのか。使いにくいな。
スマソちょっと修正。 template <typename T> struct Input { T operator()(T& t) { std::cin >> t; return t; } };
入力にtransformはねぇだろ。 template< typename T > struct input_from_cin { T operator () () { T temp; cin >> temp; return temp; } }; int main() { vector< int > v; generate_n( back_inserter( v ) , 10 , input_from_cin< int >() ); copy( v.begin() , v.end() , ostream_iterator< int >( cout , " " ) ); }
なるほど、皆さんありがとです。
>>848 copy_n は知らなんだです。gccのSTLにはあるみたいなんで良さそうですね。
でも確かに
>>853 のような事に
>>851 それだと <unknown type> なんですか?そもそもこのエラーメッセージが良く分からんっす。
ちゃんと iostream は include してるから未知って事は無いと思うんですが…
>>852 まぁもちろんファンクタ作ればいいんですが、なんとなく一行野郎で行きたかったんで…
>>855 そうなんですが、一行野郎を目指したら個数を指定する為に無理矢理行き着いたのが
transform でして…可読性はゼロですけどね(w
for_each( v.begin(), v.end(), cin >> boost::lambda::_1 ); とか言ってみる。
>>857 基本を忘れてますた…(w
# 基本か?
lambdaはなぁ・・・。
どうしてもランバダと読んでしまう。
862 :
デフォルトの名無しさん :03/02/26 22:03
ランバダ算法騎士団
★あなたのお悩み解決致します!!
●浮気素行調査
彼氏、彼女、妻、夫の浮気を調査致します!!
●盗聴器盗撮機発見
あなたの部屋に誰かが仕掛けているかも!!
●行方調査
行方不明になっている家族の消息を調査致します!!
●電話番号から住所割り出し
一般電話、携帯から住所を割り出し致します!!
●ストーカー対策
社会問題ともなっているストーカーを撃退致します!!
その他人生相談からどんなお悩みでも解決いたします!!
直通 090−8505−3086
URL
http://www.h5.dion.ne.jp/~grobal/ メール
[email protected] グローバル探偵事務局
★あなたのお悩み解決致します!!
●浮気素行調査
VB、JAVA、C#、COBOLの浮気を調査致します!!
●トロイ、ウィルス発見
あなたのプログラムに誰かが仕掛けているかも!!
●行方調査
行方不明になっている変数の消息を調査致します!!
●関数名からアドレス割り出し
.dll、.objからアドレスを割り出し致します!!
●バグ対策
社会問題ともなっているバグを撃退致します!!
その他設計相談からどんなお悩みでも解決いたします!!
直通
http://pc2.2ch.net/tech/ URL
http://www.2ch.net/ メール
[email protected] 2ちゃんねるプログラム板
865 :
STL初心者 :03/02/27 13:40
vector<bool> は使うな という話を小耳にはさんだのですが、ほんとうでしょうか?
866 :
デフォルトの名無しさん :03/02/27 13:55
boolのvectorとして使うつもりならば本当です
>>865 std::vector<bool>は過去の実装の遺物です。
固定でもよければstd::bitset、可変長が必要ならboost::dynamic_bitset
を使いましょう。
別に使ってもいいと思うよ。 ただし普通のvectorだと思って使うと細かいところで問題が起こる。 あと1要素が1bitで実装されてる保証はない。
>>865 bool型へのポインタが取得できません。
870 :
STL初心者 :03/02/27 16:54
>>867 固定長じゃないんですよー
>可変長が必要ならboost::dynamic_bitset
情報どもです。あとで調べます。
>>868 >ただし普通のvectorだと思って使うと細かいところで問題が起こる。
「細かいところ」って具体的にどんなことなんでしょう?
ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
push_back(), insert(), erase() と 値の参照、設定さえできればよいのだが
このあたりのことを詳しく説明したドキュメントってどこかにないのかなぁ
それともSTLのソースを読むしかないの?
871 :
STL初心者 :03/02/27 17:03
VC++6.0 を使っているのですが、ソースを読んだり、デバッガでトレースしてみたところ vector<bool> は1要素を1ビットで表現するという特別な処理をしているようには見えませんでした。 ということは VC++6.0 であれば vector<bool> を使っても問題ないと理解してよろしいのでしょうか?
>>871 使うコンパイラに関係なくstd::vector<bool>を使っても問題ないが、
メンバ関数が返す値はboolへのリファレンスでなくてプロキシである
ことを知っておく必要がある。
>>870 さんも言っているように、
bool* p = &vecBool[x]; のようなコードがコンパイルできない。
>>870 > ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
当たり。できません。
んでもって、これができないモノは正確には「コンテナではない」んだそうです。
よって「vector<bool>はSTLコンテナではない」が成り立つとかなんとか。
なんとなく心配なら、deque<bool>を代用品に選んどくのもいいかも。
>>871 例えばVC++6 ProのSP5なら、<vector>の245行目以下で
boolをunsigned intにパックしてるが。
875 :
STL初心者 :03/02/27 19:16
>>874 あれっ、ほんとだ。
でも vector<bool> vb; と宣言し vb.push_back(true); を実行しても
class vector<_Bool, _Bool_allocator> が利用されていないように
見えるが・・・
876 :
STL初心者 :03/02/27 19:19
それに VC++6.0 で vector<bool> vb; vb.push_back(true); bool *pb = &vb[0]; をコンパイル実行してみると、問題ないようだぜ。 パックするには何かおまじないがいるのかな?
std::vector<bool>で std::vector<bool, std::allocator<bool> >か、 bool専用のアロケータが使われるかは処理系依存で さらにbool専用のアロケータの名前も規定されてない
878 :
デフォルトの名無しさん :03/03/01 23:41
VC.netで、boostのコンパイルがうまくできません。 bjamとかって標準のインストールパスにしか対応していないのですか?
最近STL使い始めた初心者です。 グローバルでSTL宣言すると12バイトのメモリリークが起きるようなんですが、 これの解消法ってどうすればいいんですか?
>>879 よーわからんけど、「12バイトのメモリリーク」 はどうやって確かめたの?
881 :
デフォルトの名無しさん :03/03/03 00:01
template <class charT> const charT *mes() { return "message"; } 質問です mes<char>(); //はOK mes<wchar_t>(); //だめ、理由はわかってます。でもどうしたらいいのでしょうか
return TEXT("message"); // ←こうかもしれない。
>>881 template <>
const wchart_t *mes()
{
return L"message";
}
>>880 あ、すみません、説明不足でした。
list<int> hoge;
という風にグローバルで宣言して、そのまま終了すると
12バイト漏れる、ということで。
メモリリークを調べるのには
_CrtDumpMemoryLeaks()
を使いました。
グローバルに静的に確保されたオブジェクトにリークもクソもないと思うが。
グローバルで宣言したクラスの コンストラクタとデストラクタが呼び出されるタイミングと _CrtDumpMemoryLeaksが呼び出されるタイミングを考えてみろ
VC6だとlocaleでリーク起こすけど using namespace std; try{ locale::global(locale("2ch")); } catch(exception &e) {} これでリーク起こす。
>>888 VC6はC Runtimeのソース付いてるから直せるぞ
>>887 あー・・・。
気付きませんでした。どうもです。
891 :
デフォルトの名無しさん :03/03/05 08:35
VC6の出力が \ になるのですが、なぜに? #include<sstream> #include<string> #include<iostream> #include<vector> using namespace std; int main() { basic_stringstream<wchar_t> S; const char c[]="圭"; size_t size = mbstowcs(NULL,c,0); vector<wchar_t> tmp(size+1); wstring data; mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size); *(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0'; S << &tmp[0]; S >> data; wcout << data;// VC6だと\, VC.NETだと圭 }
まず、setlocaleしる。 > mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size); > *(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0'; ここのキャストは要らないと思うんだけど。 mbstowcs(&tmp[0],c,size); tmp.back() = L'\0'; これでいいはず。 んで、試してみたけど。 wcout << &tmp[0] << endl;// 「圭」 wcout << S.str() << endl;// 「圭」 wcout << data << endl;// なにもでない > S >> data こいつがうまくいかないみたい。 原因は追いきれなかった。
893 :
デフォルトの名無しさん :03/03/05 11:29
VC6.0です(STL?)。 Redo/Undoの機能をつけるために ポインタをポインタの配列で管理しようとしているのですが 配列のサイズを決めて新しい要素を入れると 古いものから順に消していってくれるような都合のいい クラステンプレートってないですか?
894 :
デフォルトの名無しさん :03/03/05 11:35
>>892 >setlocale(LC_ALL,"Japanese");を忘れてました。
ライブラリ側の問題ぽいので
S.str()で回避して使っていこうと思います。
ありがとうございました。
>>893 std::queueのラッパーでいいんじゃねーの。
キュー、っつーかリングバッファだな。 リングバッファを実現するコンテナアダプタはSTLの解説で幾つか見たことあるが、 公開されてるものはない気がするから自分で作ったほうがはやそう。
>>895 , 896
どっかから参考になりそうなものを探して自作することにします。
ありがとうございました。
FIFOバッファだからdeque使えばいいだけの話じゃないの?
stlport_vc6.dll を stlport.dll にリネームして使いたいと思います。 方法がわかる方はいらっしゃいませんか? いらっしゃいましたら、方法を教えてください。 まさか stlport_vc6.lib をバイナリ・エディット?
900 :
デフォルトの名無しさん :03/03/05 17:56
G++でwcoutを使うにはどうすればよいのでしょうか?
901 :
デフォルトの名無しさん :03/03/05 18:21
std::vector<std::string> a; ってやっちゃだめなの?
903 :
デフォルトの名無しさん :03/03/05 19:08
vector<bool>を使ったらだめな理由がわかりません。 つーか便利だよ vector<char>だと8倍メモリくうし bool *p=&vec[0]; これができないとなんでだめなんだよー
904 :
デフォルトの名無しさん :03/03/05 19:16
905 :
デフォルトの名無しさん :03/03/05 19:23
>>902 vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
なんかあやしいきもするんですが・・・
>vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど VC6発見 #pragma warning (disable : 4786) ソースの先頭に置いときなさい
>>885 ちょいと遅レスだがたしかSTLは効率のために内部にちょびっと
つねにメモリもってるらしいよ。どっかの過去ログにあるはず。
で、どっかで何かをdefineすればなくなるがパフォーマンス
悪くなる。(ってことなのかな?的外れだったらスマソ)
>>908 そういうのはメモリリークとは言わないけどね。
>>908 メモリプールといいます。そういうのは。
911 :
デフォルトの名無しさん :03/03/06 02:33
コンテナとかはstlport使ってるんですが、 stlportのiostreamを使う利点はあるのですか? static-linkだと容量でかくなるし もしたいした違いがないならコンパイルせずに 標準のiostream使おうと思うので 教えてください
912 :
デフォルトの名無しさん :03/03/06 12:01
STLportのCVSにWinCVS(or TortoiseCVS)でアクセスできませんか?
もちろん、読み取りだけで十分です。
>>900 glibc のバージョンが古いと思われ。
glibc-2.2(だったかな?)以降が入ってる環境を使うべし。
915 :
デフォルトの名無しさん :03/03/07 05:41
set<string> coll; という変数宣言がされている状況で、 for_each(istream_iterator<string>(cin), istream_iterator<string>(), coll.insert); としたいんだけど、gcc-2.95.3 では no matching function for call to `for_each (istream_iterator<string>, istream_iterator<string>, {unknown type})' とエラーになってしまう… (本当はもっとエラーメッセージが長いけど、適宜省略) プロ言C++第3版の13.2.3を見ると「テンプレート引数としては…メンバに対す る多重定義されていないポインタなどが使える」とあって、これからすると、 このset<string>::insertみたいな多重定義されているメンバ関数はテンプレート 引数としては渡せないような気もするんだけど、これって本当?
やりたいことは、下記のような関数オブジェクトInserterを作って、 template<class Collection>class Inserter { private: Collection *container; public: Inserter(Collection &c) { container = &c; } void operator()(const typename Collection::value_type &v) { (*container).insert(v); } }; coll.insert の代わりに Inserter< set<string> >(coll) と書けば できたけど、なんか納得いかないというか、イマイチGenericじゃない 気がしてる。実際、for_eachを手で展開して istream_iterator<string> in(cin); while (in != istream_iterator<string>()) coll.insert(*in++); とすれば動くだけに、なんかクヤしい。 なんか良い手ないかしら?
std::insert_iterator, std::inserterというのがあるわけだが。
#include <iostream> #include <set> #include <string> #include <iterator> #include <algorithm> int main() { std::set<std::string> sset; std::copy( std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::inserter(sset,sset.begin())); std::copy(sset.begin(),sset.end(),std::ostream_iterator<std::string>(std::cout,"\n")); return 0; }
>>916 std::set<std::string> coll;
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::insert_iterator<std::set<std::string> >(coll, coll.begin()));
std::setに関するstd::insert_iterator()の定義はちょっと面白いようになっている。
c.insert(p, t) を呼び出すわけだが、std::setではinsertのメンバ関数は探索位置を
指定する必要はない。だが互換性のためにヒントとしてパラメータを持っている。
そのためstd::insert_iterator()が使えるのである。
std::back_inserter()は使えない。なぜならstd::setはpush_back()というメンバ関数を 持たないからだ。
>>918-920 ども。それは分かります。
ただ、915-916 で言いたかったのは、この処理は間違いなく
for_eachイディオムで書ける筈だし、実際マクロならFOR_EACH
の形で書けので、templateでだって可能じゃないのか、916で
やったように、insertをハードコードすることなく、(Scheme
なら lambda を使って簡単に書けるわけだから) C++ でもなにか
方法がある筈じゃないのかってことなんでした。
もっとも 915-916を書いた時点では、自分でも何が気に入ら
なかったのかはっきりしてなかったので、うまく書けませんでした。
で、915で書いた推測は全く見当はずれでした。 3点大きな間違いがあって、まずそもそも「coll.insert」 っていうのは、C++ の文法上許されない表現なので、 template関数の引数には書けません。(^^; 正しい表現は &set<string>:insert となりますが、 この場合、&set<string>:insert だけでなく coll も 別に渡してやる必要がありました。 それから、この場合、coll.insert を渡している場所は テンプレート引数ではなく、テンプレート関数の通常の 引数なので、くだんのプロ言C++第3版の13.2.3の記述は そもそも関係ありませんでした。 最後に、ちゃんと確認してみたところ、使っている処理系 (gcc-2.95.3)だと、多重定義されているメンバ関数を テンプレート引数として渡すことだって可能でした。 (gccの拡張機能?)
で、922で書いたようにcollも渡す必要があるわけで、 mem_fun_refに習って、次のような関数オブジェクトを定義しました。 template<typename ReturnType, typename Class, typename Arg1Type> class obj_mem_fun1_t : public unary_function<Arg1Type, ReturnType> { private: Class *object; ReturnType (Class::*memfun)(Arg1Type); public: explicit obj_mem_fun1_t(Class &o, ReturnType (Class::*mf)(Arg1Type)) : object(&o), memfun(mf) {} void operator()(Arg1Type a1) { ((*object).*memfun)(a1); } }; template <typename ReturnType, typename Class, typename Arg1Type> inline obj_mem_fun1_t<ReturnType, Class, Arg1Type> obj_mem_fun(Class &object, ReturnType (Class::*mf)(Arg1Type)) { return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf); }
これで、 for_each( istream_iterator<string>(cin), istream_iterator<string>(), obj_mem_fun(coll, &set<string>::insert)); とすればOKかなと思ったんですが、gcc-2.95.35だと no matching function for call to `obj_mem_fun (set<string> &, {unknown type})' となってしまいました…
しかし、テンプレート引数を明示的に指定して for_each( istream_iterator<string>(cin), istream_iterator<string>(), obj_mem_fun< pair<set<string>::const_iterator, bool>, set<string>, const set<string>::value_type & >(coll, &set<string>::insert)); とすればコンパイルもでき、動作しました。 これで、915-916で思ってたことは、ほぼ満足です。 (テンプレート引数を明示しなければいけないのが ちょっと残念だけど。)
で、またまた疑問なんですが、のコンパイルエラーは 仕様なんでしょうか、バグなんでしょうか、それとも 未定義な部分(実装上の制限)なんでしょうか? それから、こういう、オブジェクトに対する呼びだし obj.message(arg1) を普通の関数呼びだし func(arg1) の形式に変換する関数アダプタって、標準的にあって も良さそうな気がするんですが、boost とか、そういう 準標準ライブラリとして、こういうものってないんで しょうか?
< で、またまた疑問なんですが、のコンパイルエラーは う、書き間違えました。これは > で、またまた疑問なんですが、924のコンパイルエラーは でした。
boostのbindを調べてください
template <typename ReturnType, typename Class, typename Arg1Type,typename Class2> inline obj_mem_fun1_t<ReturnType, Class, Arg1Type> obj_mem_fun(Class2 &object, ReturnType (Class::*mf)(Arg1Type)) { return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf); } こうしたらVC7でとおった
>>928 ドキュメントを読んで下記を試してみたところ、期待通りに
動作しました。
for_each(
istream_iterator<string>(cin),
istream_iterator<string>(),
boost::bind< pair<set<string>::const_iterator, bool> >(
boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
素晴らしいです。どうもありがとうございました。
最初は下記のやり方を試したんですが、こちらの書き方だと、
自作のもっと単純な型に対しては動くんですが、set<string>
に対しては、924 と同様の症状でコンパイルに失敗してしまいました。
for_each(
istream_iterator<string>(cin),
istream_iterator<string>(),
boost::bind(&set<string>::insert, boost::ref(coll), _1));
>>931 > boost::bind< pair<set<string>::const_iterator, bool> >(
> boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
その使い方だったらboost持ち出すまでもなく
bind1st<...>( mem_fun(&set<string>::insert), &coll )
でよくない?
>>932 なるほど。言われてみれば確かにその通りです。
mem_funを使って
for_each(
istream_iterator<string>(cin),
istream_iterator<string>(),
bind1st(
mem_fun<
pair<set<string>::const_iterator, bool>,
set<string>,
const set<string>::value_type &
>(&set<string>::insert),
&coll));
とするか、あるいはmem_fun_refを使って
for_each(
istream_iterator<string>(cin),
istream_iterator<string>(),
bind1st(
mem_fun_ref<上に同じ>(&set<string>::insert),
coll));
とすれば、うまく行く筈ですね… と思ってやってみたら、
例の「参照への参照」問題が発生して、どちらもコンパイル
エラーになってしまいました…
bind1stが定義する関数オブジェクトの呼びだし時に、
set<string>::insert() の引数型(const string への参照です)
への参照型を使って渡そうとするのが、原因のようです…
うーんgcc3.2.2(MinGW)ではコンパイルに失敗するね。 移し間違えているのかな? std::set<std::string> coll; std::for_each( std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), boost::bind<std::pair<std::set<std::string>::const_iterator, bool> >( boost::mem_fn(&std::set<std::string>::insert), boost::ref(coll), boost::lambda::_1)); C:/MinGW/boost/set_insert.cpp: In function `int main()': C:/MinGW/boost/set_insert.cpp:19: no matching function for call to ` mem_fn(<unknown type>)'
あれれ、unknown typeになりますか。mem_fn()のテンプレート引数を 明示的に指定するとどうでしょう? set<string> coll; for_each(istream_iterator<string>(cin), istream_iterator<string>(), boost::bind< pair<set<string>::const_iterator, bool> >( boost::mem_fn< pair<set<string>::const_iterator, bool>, set<string>, const set<string>::value_type & >(&set<string>::insert), boost::ref(coll), _1)); 手元の環境だと、この場合、bind()の方のテンプレート引数は 省略可能になります。
>>935 さらに強烈なエラーが出てきました。
C:/mingw/include/boost/bind.hpp: In member function `R boost::_bi::list2<A1,
A2>::operator()(boost::_bi::type<R>, F, A&) const [with R =
std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, F =
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const
std::string&, const std::string*>, bool>, std::set<std::string,
std::less<std::string>, std::allocator<std::string> >, const std::string&>,
A = boost::_bi::list1<const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&>, A1 =
boost::reference_wrapper<std::set<std::string, std::less<std::string>,
std::allocator<std::string> > >, A2 =
boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
> >]':
C:/mingw/include/boost/bind/bind_template.hpp:33: instantiated from `boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&) [with A1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, F = boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>, L = boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>, std::allocator<std::string> > >, boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > >]' C:/mingw/include/c++/3.2.2/bits/stl_algo.h:157: instantiated from `_Function std::for_each(_InputIter, _InputIter, _Function) [with _InputIter = std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>, _Function = boost::_bi::bind_t<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>, boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>, std::allocator<std::string> > >, boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > > >]'
C:/MinGW/boost/set_insert.cpp:23: instantiated from here C:/mingw/include/boost/bind.hpp:233: no match for call to `( boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>) (std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)' C:/mingw/include/boost/bind/mem_fn_template.hpp:129: candidates are: R boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, T = std::set<std::string, std::less<std::string>, std::allocator<std::string> >, A1 = const std::string&] C:/mingw/include/boost/bind/mem_fn_template.hpp:134: R boost::_mfi::mf1<R, T, A1>::operator()(U&, A1) const [with U = std::set<std::string, std::less<std::string>, std::allocator<std::string> >, R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, T = std::set<std::string, std::less<std::string>, std::allocator<std::string> >, A1 = const std::string&] C:/mingw/include/boost/bind/mem_fn_template.hpp:139: R boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>, T = std::set<std::string, std::less<std::string>, std::allocator<std::string> >, A1 = const std::string&] Execution terminated
939 :
デフォルトの名無しさん :03/03/08 22:05
string文字列中の特定の文字Aを検索し、 その文字以降Bが出現するまでの文字列を抜き出したい場合 どうすればよいですか。 string str(`hoge...`); string::iterator sp; string::iterator ep; sp = find(str.begin(), str.end(), 'A'); ep = find(sp, str.end(), 'B'); で要素位置はわかりますが、これをどう使えば 要素を抜き出せるのか。。。
string str("fawAejkreBf"); string::size_type pos=str.find_first_of('A'); if(pos!=string::npos) { pos++; str=str.substr(pos,str.find_first_of('B',pos)-pos); }
>>939 string AtoB(sp, ep);
>>936 エラーは no match for call to ですか…
なんかメソッドの signature が違っているくさいですね。
コンパイラというよりは、STL の実装の違いのような気が
するんですが、UNIX系OS上の gcc-3.2.1 では 935で問題
なく通りました。gcc-3.2.1と3.2.2で、STL回りって、
そんなに変わっているんでしょうか。
>>942 原因がわかりました。_1 はてっきり boost::lambda::_1 かと思ってたの
ですが、boost::bind の _1 だったのですね。
無事通りました。ありがとうございます。
gcc3.2.2でも通りました(当たり前ですよね)。
ただ、やはり boost:mem_fn のテンプレート引数を明示的に指定しないと
コンパイル通りません。
945 :
デフォルトの名無しさん :03/03/11 12:20
std::ofstream ofs("test.bin",std::ios::binary); int tmp = 12; ofs << tmp; こうしても、バイナリ出力にはなりませんよね。 fstream系でバイナリ入出力って無理なんですか? もひとつ。 template<typename T> void Hoge(const T& t){ /* 省略 */} に対して、Tが vector<T> みたいなものだった場合は 別なことをさせたいんですが、特殊化でしょうか。 あくまでvector<T>です。まだ型は完全に 決まってないので、部分特殊化なんでしょうか? VC6で、どうやればいいんでしょうか……?
>>945 バイナリイメージの出入力なら、std::ios::binary付けたうえで、
reinterpret_cast&read/writeかな。
VC6でふつうに部分特殊化したらエラーになった。
サポートできてないんだっけ?
>>945 部分特殊化というよりは、template関数のpartial ordering。
確かVC6では使えないので、何かトリックを使って頑張るしか無いのでは。
948 :
デフォルトの名無しさん :03/03/13 17:40
微妙にスレ違いですが、質問お願いします。 stringから、整数や実数に直接入力する方法ってありますでしょうか。 今は下記のようにやっています。 string str = "777"; int c = atoi(str.c_str()); なんていうかstdlib.hをインクルードするのが悔しいというか・・・アホですいません。 ストリームみたいに、stream >> intみたいな感じで可能ならなぁ、と。
>>948 boost::lexical_cast 使え…とかそういう話?
ミスって投稿しちゃった。こんな感じ。 #include <string> #include <boost/lexical_cast.hpp> int main(int argc, char **argv) { string str = "777"; int c = boost::lexical_cast<int>(str); return 0; }
>>950 すごい!
・・・・boostってすごい_| ̄|○
λ...........オトシテコヨウ…
と、レスありがとうございました。すいません、環境書かなくて…。
今は腐ったVC++6付属の使ってますが、これを機に移行してみようと思います。
>>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 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。