【C++】template 統合スレ -- Part6

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。
STLスレッド
Part1 http://pc.2ch.net/tech/kako/1004/10042/1004287394.html
Part2 http://pc3.2ch.net/tech/kako/1026/10267/1026793823.html

【C++】Boost使い集まれ!
http://pc3.2ch.net/test/read.cgi/tech/1033830935/ (html化待ち?)

Generic Programming with C++ Template
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
【C++】template 統合スレ -- STL/Boost/Loki, etc.
http://pc2.2ch.net/tech/kako/1037/10377/1037795348.html
【C++】template 統合スレ -- Part2
http://pc2.2ch.net/test/read.cgi/tech/1047978546/ (html化待ち)
【C++】template 統合スレ -- Part3
http://pc5.2ch.net/test/read.cgi/tech/1066493064/ (html化待ち)
【C++】template 統合スレ -- Part4
http://pc5.2ch.net/test/read.cgi/tech/1083550483/ (html化待ち)
【C++】template 統合スレ -- Part5
http://pc5.2ch.net/test/read.cgi/tech/1091522597/
関連スレ、その他リンクは >>2-5 あたりに。
2デフォルトの名無しさん:04/11/25 21:12:08
3デフォルトの名無しさん:04/11/25 21:12:30
boostに関する有名な日本語サイト

・boost info
http://shinh.skr.jp/boost/

・boost::spiritっちゃえ!
http://www.c3.club.kyutech.ac.jp/~gridbug/spirit/

・Let's boost
http://www.kmonos.net/alang/boost/

・Regex
http://www.s34.co.jp/cpptechdoc/article/regexpp/

・Boostを使おう
http://www.emaki.minidns.net/Programming/tools/Boost/
4デフォルトの名無しさん:04/11/25 21:12:51
参考図書

・テンプレート
C++ Templates
http://www.amazon.com/exec/obidos/ASIN/0201734842/
Modern C++ Design
http://www.amazon.co.jp/exec/obidos/ASIN/4894714353/
C++ Template Metaprogramming
http://www.amazon.co.jp/exec/obidos/ASIN/0321227255/

・Boost関連
Boost C++ Libraryプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4798007862/
The Boost Graph Library
http://www.amazon.co.jp/exec/obidos/ASIN/0201729148/

・STL
Generic programming―STLによる汎用プログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4756134416/
Effective STL
http://www.amazon.co.jp/exec/obidos/ASIN/4894714108/
STLによるコンポーネントデザイン
http://www.amazon.co.jp/exec/obidos/ASIN/475613422X/
5デフォルトの名無しさん:04/11/25 23:45:32
追加

C++ Template Metaprogramming
: Concepts, Tools, and Techniques from Boost and Beyond
http://www.amazon.com/exec/obidos/tg/detail/-/0321227255/

Dependancy Inversion Principle
http://www.objectmentor.com/publications/dip.pdf
6デフォルトの名無しさん:04/11/26 01:17:17
>>1
  _n
 ( l    _、_
  \ \ ( <_,` )
   ヽ___ ̄ ̄  )   グッジョブ!!
     /    /
7デフォルトの名無しさん:04/11/26 19:54:41
C++相談室に統一すれば良かったのに.....
8デフォルトの名無しさん:04/11/26 20:07:43
ここを相談室と統一するのはどうかと思うけどな。
9デフォルトの名無しさん:04/11/26 20:20:50
STLスレとBOOSTスレとこのスレを統合すべきだよね。
10デフォルトの名無しさん:04/11/26 20:24:21
いやC++相談室とこことSTLスレが統合して(つまり標準)
BOOSTを分けるべきじゃ?
個人的には上のは全部一つのスレでいいとは思うんだけど
1110:04/11/26 20:25:30
おっとここは標準じゃないんだったか
12デフォルトの名無しさん:04/11/26 20:37:47
BOOSTはSTLの拡張みたいなものだから同じスレで良いと思う。
そもそもBOOSTなんてただの一ライブラリに過ぎないのにスレをわける必要があるの
だろうか。
13デフォルトの名無しさん:04/11/26 20:47:05
MFCやATLでスレたってるじゃん
14デフォルトの名無しさん:04/11/26 20:49:01
BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから

BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから

BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから
BOOSTはSTLの拡張みたいなものだから
15デフォルトの名無しさん:04/11/26 20:57:23
1には申し訳ないが
ここと【C++】STL(Standard Template Library)相談室はもういらんだろう
以後は話題によって如何に書くべし
BOOSTを語れゴラァ
C++相談室 part37
【初心者歓迎】C/C++室 Ver.12【環境依存OK】
16デフォルトの名無しさん:04/11/26 20:59:48
C++スレで質問する初心者はだいたい標準C++及びSTLでの回答を期待してると思うんだ。
だからこれらは一緒にしてもいいと思う。
17デフォルトの名無しさん:04/11/26 21:01:56
以前はLokiとかも考慮してここが立ってたのにな。
前みたいにスレタイにBoostやLokiを入れてれば重複スレに置き換わられることも無かったろうに。
18デフォルトの名無しさん:04/11/26 21:08:14
Lokiに限定した質問て最近ほとんどないので現状では

BOOSTを語れゴラァ
C++相談室 part37

どっちかに振れば良いと思う
「BOOSTを語れゴラァ」の次スレあたりで
Lokiの名前を加えるといいのではないでしょうか
19デフォルトの名無しさん:04/11/26 21:11:20
AssocVectorについて
20デフォルトの名無しさん:04/11/26 21:15:20
Loki って使いものになります?業務で。
21デフォルトの名無しさん:04/11/26 21:15:45
>「BOOSTを語れゴラァ」の次スレあたりで
>Lokiの名前を加えるといいのではないでしょうか

それはつまり内容的にここのことじゃないか。
22デフォルトの名無しさん:04/11/26 21:18:32
標準C++相談室【STL含む】スレと
C++テンプレート相談室【Boost/Loki】スレ
があればいいんだ。
これでスレタイで検索できるから重複も立たないし、
質問する人もわかりやすい。
23デフォルトの名無しさん:04/11/26 21:19:43
>>20
あなたには無理です
24デフォルトの名無しさん:04/11/26 21:24:24
>>22
いいですね
C++相談室は今のスレが950くらいになったら
次スレの名前として「標準C++相談室【STL含む】」を提案しましょう

で「C++テンプレート相談室【Boost/Loki】スレ」はどうします?
25デフォルトの名無しさん:04/11/26 21:25:13
boostってそもそもtemplateじゃないのも多いのに
26デフォルトの名無しさん:04/11/26 21:25:36
>>23
誰なら使い物になりますか?
27デフォルトの名無しさん:04/11/26 21:27:34
>>25
別にC++非標準ライブラリ相談室でもいいぞ
28デフォルトの名無しさん:04/11/26 21:33:59
>>20
実際の開発で Loki 使っている人いる?是非聞きたいなー。
29デフォルトの名無しさん:04/11/26 21:34:31
crypto++とかについて話せるスレがやっとできるのか
30デフォルトの名無しさん:04/11/26 21:36:15
lib*のC++インターフェースが用意されてない事も多いから
C/C++非標準ライブラリ相談室にしよう。
31デフォルトの名無しさん:04/11/26 21:39:30
C/C++非標準ライブラリ相談室【Boost/Lokiなど】

とライブラリ名を入れるのを忘れないようにしよう。
入れないと絶対重複スレ立てる人いるから。
32デフォルトの名無しさん:04/11/26 21:45:15
C++アブノーマル相談室
33デフォルトの名無しさん:04/11/26 21:46:50
>>31
「C/C++非標準ライブラリ」というと標準以外全部含みそうなので(まぁBoost/Lokiなどといれてるけど)
C/C++環境非依存ライブラリ相談室【Boost/Lokiなど】
C/C++准標準ライブラリ相談室【Boost/Lokiなど】
とかどうでしょうか?
34デフォルトの名無しさん:04/11/26 21:50:08
>>33
標準以外全部含んでいいんじゃないの?
専用スレがあったら誘導すればいいんだし。
そのスレタイだと初心者が迷いそう。
そもそもスレタイは初心者が迷わないために工夫するんだし。
3533:04/11/26 21:55:10
>>34
>そもそもスレタイは初心者が迷わないために工夫するんだし。
そうかもしれない

じゃ自案は取り下げて如何を支持します
C/C++非標準ライブラリ相談室【Boost/Lokiなど】
36デフォルトの名無しさん:04/11/26 21:57:43
そうすると今後は純粋にtemplateについての質問は
標準スレに回ることになるんですよね?
そこらへんは「柔軟に」ってことで良いのかな?
37デフォルトの名無しさん:04/11/26 22:00:31
標準スレだろ
38デフォルトの名無しさん:04/11/26 22:06:17
もういまどきテンプレート関数やクラスをC++じゃないなんて
言う奴もいないだろ?
39デフォルトの名無しさん:04/11/26 22:20:09
CとC++は分けたほうがいいと思うなぁ…
40デフォルトの名無しさん:04/11/26 22:27:48
分けられるとlibpngをC++で使いたい時とか困るよなあ…
41デフォルトの名無しさん:04/11/26 22:56:58
標準か非標準かよりも(比較的)汎用か非汎用かの方がスレを分ける際に重要だと思うけど。
MFCがC++スレに混ざってたら、大半の人にとっては無関係な話題が延々繰り返されるわけでうざくてしょうがないが、
boostもLokiもある程度の環境で使えるんだからみんな全く無関係ってほどでもないだろ?
42デフォルトの名無しさん:04/11/26 22:58:04
MFCは専用スレが既にあるから問題無いと思うが
43デフォルトの名無しさん:04/11/26 23:01:11
>>41
それってポータブルかどうかってことだと思うんだけど
訳は汎用でいいの
44デフォルトの名無しさん:04/11/26 23:03:32
>>43
気にするな。いい日本語が思いつかなかっただけだ。
45デフォルトの名無しさん:04/11/27 00:16:33
>>41
標準 / 非標準環境非依存 / 非標準環境依存 の3通りだな
...表記長いな
46デフォルトの名無しさん:04/11/27 17:22:23
ところで
boost/algorithm/string/replace.hppの
//! Replace all algorithm
...
\return A reference to the modified input
*/
って間違いだよね?replace_allは戻り値voidだし。
47デフォルトの名無しさん:04/11/27 21:39:17
コピペしたときに消し忘れたっぽいね。
4846:04/11/28 00:02:14
むしろその方が使いやすいような気がするんだけどなぁ。俺が自分で
作って使っていたreplace_allは名前が同じで引数がまったく同じシグニチャで
戻り値だけが違って変更後の文字列への参照を返してた。
49デフォルトの名無しさん:04/11/28 00:08:42
In place modificationはvoidを返すんでいいよ。
プロトタイプ見ただけでin placeであることが分かる。
50デフォルトの名無しさん:04/11/28 00:14:09
あぁ、なるほど。そういう考え方の切り口があったのか。
アリガトン。
51デフォルトの名無しさん:04/12/02 10:34:53
以下のコードをビルドするとリンカで外部参照未解決というエラーがでます
template<class T> T Test(T t){ return t; }
//template int Test<int>(int);   //明示的に生成
int main(){
  //Test<int>(0);          //普通に使用
  boost::bind(Test<int>, 1);
  return 0;
}
どちらかのコメントをとると上手くいきますが、こういう仕様でしょうか?
52デフォルトの名無しさん:04/12/02 10:36:13
>>51 VC6か?
53デフォルトの名無しさん:04/12/02 10:43:27
>>52
そうです
54デフォルトの名無しさん:04/12/02 10:46:17
捨てるしか
55デフォルトの名無しさん:04/12/02 11:08:46
>>54
そうですか。2005まで粘ろうかなぁ。なんて。あははhっは
56デフォルトの名無しさん:04/12/02 11:18:16
2005 までは Toolkit とか 2005 Beta とか 2005 Express 使ってりゃいいじゃん
VC6 はさっさと捨てろ
57デフォルトの名無しさん:04/12/02 12:29:27
貧乏人は死ね
58デフォルトの名無しさん:04/12/02 12:58:30
優越感に浸りたいお年頃
59デフォルトの名無しさん:04/12/02 13:44:50
うちは金持ちだけど6.0
60デフォルトの名無しさん:04/12/02 13:52:18
ダメじゃん。
61デフォルトの名無しさん:04/12/03 03:22:13
>>59
金持ちだけど技術なし?
62デフォルトの名無しさん:04/12/09 01:13:37
下がりすぎage
63デフォルトの名無しさん:04/12/09 01:36:48
template=天ぷらって?
64デフォルトの名無しさん:04/12/09 01:39:31
>>63
10点
65デフォルトの名無しさん:04/12/09 02:31:21
10点ならいいじゃん。
オリンピックだって10点満点で評価してるしな。
66デフォルトの名無しさん:04/12/09 02:37:49
違う。1000点満点中の10点だ。よく覚えとけ。
67デフォルトの名無しさん:04/12/09 18:13:18
boostの質問はここでいいのでしょうか?
以下のようにboost::bindを二重に使うと上手くキャストできません。
二回目のBase&を渡すところで内部でコピーされてスライスされているのでしょうか。
ポインタで渡せば問題ないのですが、参照で保持してくれるようにはできませんか?

struct Base { virtual ~Base() {} };
struct Hoge : public Base { };

void bar ( Base& b ){
  if ( Hoge *p = dynamic_cast<Hoge*>(&b) )
    std::cout << "bar ok" ; //ここへはこない
}

void foo ( Base& b ){
  if ( Hoge *p = dynamic_cast<Hoge*>(&b) )
    std::cout << "foo ok" ;

  boost::bind ( &bar, b )();
}

int main(){
  Hoge hoge;
  boost::bind ( &foo, hoge )();
  return 0;
}
68デフォルトの名無しさん:04/12/09 18:19:54
boost::bind ( &foo, boost::ref( hoge ) )();
69デフォルトの名無しさん:04/12/09 18:26:04
間違えた
-boost::bind ( &bar, b )();
+boost::bind ( &bar, boost::ref ( b ) )();
-boost::bind ( &foo, hoge )();
+boost::bind ( &foo, boost::ref ( hoge ) )();
70デフォルトの名無しさん:04/12/09 18:28:55
bindが引数の型を推論するときにBase &のtop-level referenceを剥いじゃうんですよね・・・
71デフォルトの名無しさん:04/12/09 18:30:22
>>69
67の例だとhogeをラップする必要はないですよ.
72デフォルトの名無しさん:04/12/09 18:36:09
即答ありがとうございます。上手くキャストされました
73デフォルトの名無しさん:04/12/12 14:38:59
listのメンバであるsort関数についてお尋ねしたいのですが、
これの引数であるCompare compというのはどういう物なのでしょうか。

関数オブジェクトやfunctionalの物かと思って色々試してみたのですが、どうにも上手くいきません。
74デフォルトの名無しさん:04/12/12 14:51:30
普通に二項の関数オブジェクト
7573:04/12/12 15:19:55
すいません、functionalでもgreaterだけは通りました。
lessやless_equal、greater_equalでは駄目みたいです。

>>74
レスありがとうございます。では私の何かやり方がまずいっぽいです。
どうか添削して頂けないでしょうか。

#include <iostream>
#include <list>
using namespace std;

struct func_object{
bool operator()( const int& lhs, const int& rhs ){
return lhs < rhs;
}
};

int main(){
list<int> list_hage;
list_hage.push_back( 5 );
list_hage.push_back( 1 );
list_hage.push_back( 3 );

list_hage.sort( func_object() ); //error: struct func_objectから、struct std::greater<int>に変換できません(VC6)

//確認用
for( list<int>::iterator it = list_hage.begin(); it != list_hage.end(); ++it ){ cout << (*it) << endl; }
return 0;
}
76デフォルトの名無しさん:04/12/12 15:41:31
>>75
コンパイラがまずいんじゃないの?gcc3.4.2では普通に通るぞ。

#include <iostream>
#include <list>

struct func_object {
bool operator()(const int& lhs, const int& rhs) const {
return lhs < rhs;
}
};

int main()
{
std::list<int> list_hage;

list_hage.push_back(5);
list_hage.push_back(1);
list_hage.push_back(3);

list_hage.sort(func_object());

//確認用
for (std::list<int>::const_iterator it = list_hage.begin(); it != list_hage.end(); ++it)
std::cout << *it << std::endl;
}
77うすげ:04/12/12 15:43:16
hogeの代わりにhageを使うヤツは嫌い。
78デフォルトの名無しさん:04/12/12 15:54:32
だからVC6じゃC++は使えないんだって何度言えば
79デフォルトの名無しさん:04/12/12 15:56:45
>>76
確認ありがとうございます。おかげですっきりしました。
勉強中の身ですし、頭からコンパイラのせいだ!とは言いづらく…。

>>77
私も眉毛と生え際の間がフォーフィンガーでして、自嘲の意味で良く使うのですが、配慮が足りずすいません。
80つる:04/12/12 16:03:40
>>うすげ
気にするな
個性だ
81デフォルトの名無しさん:04/12/12 21:56:38
こんどからusageの替わりにusugeを使おう。
82デフォルトの名無しさん:04/12/14 23:42:13
偉大なるstroustrupに敬意を示すため
我々C++プログラマは、むしろ積極的にhageを使っていくべきじゃなかろうか
83Addicted to C++ ◆nrBjarne.g :04/12/14 23:44:30
むしろ積極的にトリップにBjarneを入れていくべきではないだろうか。
84デフォルトの名無しさん:04/12/16 16:49:49
>>78
意味不明。
85デフォルトの名無しさん:04/12/16 17:28:50
つまり
VC++6使ってる奴は貧乏人
っていうことですよ
86デフォルトの名無しさん:04/12/16 17:38:24
決して割れに手を出さない分、高貴とも言える
87デフォルトの名無しさん:04/12/16 18:12:58
金が無いならvc2005 betaでも使えば良いだろ。
88デフォルトの名無しさん:04/12/16 19:35:46
金が無いならVCTKでも使えば良いだろ。
89デフォルトの名無しさん:04/12/16 21:13:44
金がないならハンドコンパイルすればよいだろ。
90デフォルトの名無しさん:04/12/17 11:45:57
Boost.Spirit見てて思ったんだが、
同じようにSQLクエリをC++で記述できないもんかな。

sql.select( Person.name, Person.sex ).from( Person ).where( Person.age>=20 );

ってな感じで。
91デフォルトの名無しさん:04/12/17 12:40:12
>>90
わらった。変態すぎ。
92デフォルトの名無しさん:04/12/17 13:36:33
>>90
ちょっと面白そう
93デフォルトの名無しさん:04/12/17 23:54:26
>>90
今作ってるオリジナル言語のコンパイラが完成したら
開発に着手する気でいたw
94デフォルトの名無しさん:04/12/18 13:24:58
95デフォルトの名無しさん:04/12/25 14:39:04
T1 と T2 が整数型という前提で sizeof(T1) > sizeof(T2) の時に
T2型の整数をゼロ拡張してT1型の整数に変換するテンプレート関数
はどのように書けばよいでしょうか?

template<class T1, class T2>
T1 zero_ext( const T2& x );
96デフォルトの名無しさん:04/12/25 16:34:01
ゼロ拡張?
意味不明。
俺用語を使うな。
97デフォルトの名無しさん:04/12/25 16:34:07
>>95
template<class T1, class T2>
T1 zero_ext(const T2& x)
{
return static_cast<unsigned T1>(x);
}
98デフォルトの名無しさん:04/12/25 17:05:50
99デフォルトの名無しさん:04/12/25 17:47:33
ISO C++の4.7.2にあるunsignedのintegral conversionの事でしょうね。
zero expansionってのはアセンブラの世界では良く使うね。
100デフォルトの名無しさん:04/12/25 17:51:47
>>97
それだと、T2が符号付きのときに符号拡張されちゃうんじゃないか?
101デフォルトの名無しさん:04/12/25 18:05:04
じゃあこうか?
template<class T1, class T2>
T1 zero_ext(const T2& x)
{
return static_cast<unsigned T1>(static_cast<unsigned T2>(x));
}

102デフォルトの名無しさん:04/12/25 18:06:37
そもそもunsigned T1とかできるのかな?
103デフォルトの名無しさん:04/12/25 18:15:08
よく知らんが、boost::numeric_convertionってそういう目的のライブラリじゃないのかな?
104デフォルトの名無しさん:04/12/25 19:10:36
template<typename T, typename Container = std::map<Key, T>, typename Key = std::size_t> class Tree { };
こういう順番にテンプレート引数を取りたいのですが、どうしたらいいでしょうか?
Tree<int, std::vector<T> >としたときKeyは当然不要なので省略できるようにしたいのです。
105デフォルトの名無しさん:04/12/25 19:13:29
テンプレートのデフォルト引数は一つまでだYO
106デフォルトの名無しさん:04/12/25 19:15:55
無理じゃね?
107デフォルトの名無しさん:04/12/25 19:21:17
Tree<std::vector<int> > としたときTは当然不要なので
108デフォルトの名無しさん:04/12/25 19:47:26
struct use_default{};

template <typename T, typename Container = use_default, typename Key = use_default>
class Tree{/* がんばって情報を取り出す */};

boost::iterator_adapterの実装が参考になるかも試練。
109デフォルトの名無しさん:04/12/25 19:57:26
おまえらぶーすとに踊らされすぎだぶー
110デフォルトの名無しさん:04/12/25 20:02:46
boostは一緒に踊ってくれる数少ない仲間なんだよ。
111デフォルトの名無しさん:04/12/25 20:04:43
踊る阿呆に見る阿呆、同じ阿呆なら踊らにゃソンソン
112デフォルトの名無しさん:04/12/25 21:42:20
踊らにゃシャンソン
113デフォルトの名無しさん:04/12/25 22:01:15
>>111
必ずどちらかの阿呆であるという無理な前提で人を煽るその言葉は大嫌いだ。
114デフォルトの名無しさん:04/12/25 22:24:27
2択でもなく決め付けだしな
詭弁だ
115デフォルトの名無しさん:04/12/25 22:27:59
なんで踊るよりも見る方が損なのかがわからん。
踊ったら疲れるだけなのに。
116デフォルトの名無しさん:04/12/25 22:47:49
理論(見る)より実践(踊れ)てこと
117デフォルトの名無しさん:04/12/25 22:51:29
>>115
踊ることが楽しいと言いたいのだろう。
118デフォルトの名無しさん:04/12/25 23:20:36
>>101
VC++ 7.1 だと unsigned T1 のような書き方は構文エラーになりました。
119デフォルトの名無しさん:04/12/26 00:16:22
C++Templateの便利な機能のうち
Javaでは実現できないことってなんなのかを
教えてください。
120デフォルトの名無しさん:04/12/26 00:17:25
特殊化
121デフォルトの名無しさん:04/12/26 00:18:39
ていうかほぼ全部?
122デフォルトの名無しさん:04/12/26 01:13:48
>>119
使ってすぐ分かるのは、コンテナから取り出すときにナローイング変換しなくていいこと。
123120:04/12/26 01:16:18
あれ?
Java Genericsかと思ったけど、Javaか…
124デフォルトの名無しさん:04/12/26 04:53:50
JavaのGenericsってただの自動キャストでそ?
C++のtemplateとは比較にならないのでは・・・
125デフォルトの名無しさん:04/12/26 08:56:50
.NETのgenerics、試みは面白い。
126デフォルトの名無しさん:04/12/26 13:31:14
で、結局具体的にどんなことがJavaにできなくて
C++で出切るんですか?
C++ではこんなに簡単に書けるのに
Javaで書くとこんな風になっちゃうって例を
出していただけると助かります。
いろいろ考えたんですが、特別優れた使い方ってのが
思いつかなかったので。
もしかして、ないのかな・・・
127デフォルトの名無しさん:04/12/26 20:01:11
クマー
128デフォルトの名無しさん:04/12/26 20:13:40
               .|   |  | |   |    |  | |
               .|   |  | レ  |    |  | |
    ∩___∩    |   |  |     J    |  | |
    | ノ\   ,_ ヽ  .|   レ |      |  レ|
   /  ●゛  ● |   .J      し         |     |
   | ∪  ( _●_) ミ             .|    し
   彡、   |∪|   |              .J
 /     ∩ノ ⊃  ヽ
 (  \ / _ノ |  |  
  \  "  /  | |  Javaしらね。覚える気もねえし
   \ / ̄ ̄ ̄ /
129デフォルトの名無しさん:04/12/26 20:56:55
>>126
Java Genericsは分かるの?
130デフォルトの名無しさん:04/12/28 00:49:18
>>126
「オブジェクト指向をベース」にプログラムを書いた場合
JavaのGenericsで全てが事足りる。
131デフォルトの名無しさん:04/12/28 01:22:25
速度以外はな。
132デフォルトの名無しさん:04/12/28 05:44:30
素人が首突っ込んで申し訳ないが
Javaには専用プラットフォーム必須なんだよね?


要はエミュレータ?
133デフォルトの名無しさん:04/12/28 08:33:23
>>132
プラットフォームの意味わかってんのか?
134デフォルトの名無しさん:04/12/28 12:28:32
>>126
Lokiのような変態的なライブラリは無理じゃないの?Generics知らんけど。
135デフォルトの名無しさん:04/12/28 13:19:32
その変態なLokiなんですけど、TYPELISTって動作遅くしないですか?
継承によって、多義性をサポートさせるのはよい。
コンパイル時にその多義性を作り出すのも良い。

けど、継承って、実行速度おそくなりませんか?
136デフォルトの名無しさん:04/12/28 13:24:09
>>134
あれはオブジェクト指向を捨ててるからな。
オブジェクト指向で書き直せばもっときれいなのが作れるよ。
137デフォルトの名無しさん:04/12/28 13:38:33
>>135
Modern C++ Designを読めば分かるけど、
LokiのPolicyは仮想関数を使ってないから…
138デフォルトの名無しさん:04/12/28 13:42:22
>>135
TYPELISTはコンパイル時のみ。

継承なしで巨大ライブラリを作れる人、使える人はそうしたら良かろう。
Cで書いてあるgtk+みたいなのでも継承しているけどね。
139デフォルトの名無しさん:04/12/28 13:42:58
大抵は問題にならん
140デフォルトの名無しさん:04/12/28 14:51:39
lokiはデザパタではなくてboost::mplに似ているわけか。
141デフォルトの名無しさん:04/12/28 15:23:42
たくさんのレスに感謝。
>137
Modernは読んでます。内容を完全に理解したとは言いがたいですが。
けれども、Efficient読んでるとvirtual使わない継承でも動作遅くなるよ〜。
と書いてあるもので。
「本質的な問題ではない。」が結論なんですけどね。

>138
その通りです。
継承無しでライブラリの作成…作ったことありませんがゾッとします。

>139
>大抵は問題にならん。
継承しまくったオブジェクトを生成&削除しまくるプロジェクトとか
(サーバー用途?)ではどうでしょうか?

ModernのTYPELISTの継承構造見ていると、継承の無駄が多い気がして。
p237のクラス階層とかってつまりは。
class AbstractEnemyFactory :public AbstractFactoryUnit<Soldier>,
      public AbstractFactoryUnit<Monster>, public AbstractFactoryUnit<SuperMonster>

なわけで。

実際に巨大プロジェクトの現場を経験したことのない人間の戯言ですが。
142デフォルトの名無しさん:04/12/28 15:27:43
>実際に巨大プロジェクトの現場を経験したことのない人間の戯言ですが。

自覚しているんなら黙れ。っーつか氏ね。
143デフォルトの名無しさん:04/12/28 15:28:43
>>142
お前こそ黙っとけよ。
144デフォルトの名無しさん:04/12/28 15:31:01
>>143
バーカ
145デフォルトの名無しさん:04/12/28 15:38:54
>っーつか氏ね。
OK。発音してみよう。
146デフォルトの名無しさん:04/12/28 15:48:24
>>141
それ、TYPELISTなしで書いた方が可読性悪いでしょ。
TYPELISTは実行時に負担ないしね。コンパイル時にやるから。
typeid listじゃないから。
147デフォルトの名無しさん:04/12/28 15:51:47
>継承しまくったオブジェクトを生成&削除しまくるプロジェクトとか
>(サーバー用途?)ではどうでしょうか?
メモリ確保&解放は一瞬。メモリに書き込むことは多少重いけど。
ただ、ゲームなんかのメモリ資源が超少ない環境では
メモリのフラグメントなんかが起こって、メモリが足りなくなることはある。
148デフォルトの名無しさん:04/12/28 16:01:22
いや、new/deleteは重いけど、
継承しているしていないに関係ない。

継承して複雑な部分を作り出す構造だと、
一つのオブジェクトの中にまとめられるから、
利用するメモリチャンクの数が減ることも考えられる。

Cでやると、ポインタの嵐になって別々の構造体になるから、
malloc/freeを寄り頻繁にする必要がある(事が多い)。

とりあえず、135は、
・templeteが、compile時のみ働くものであること
・詳解C++(いわゆるAnnotated)を読んで、継承のメモリ利用
を勉強しろ。

分からない奴はいつまでたっても設計ができない。
149デフォルトの名無しさん:04/12/28 16:03:14
>>148
> Cでやると、

「継承しないでやると、」の方がいいかな。

compositionとinheritanceの違いはAnnotated読んで。
150デフォルトの名無しさん:04/12/28 16:58:14
みんなRubyのこと嫌いなの?
151135:04/12/28 18:54:45

自分でTYPELISTでAbstractFactoryを組んで、それをいじくりまわしてみました。
結果:変わらないですね…
なんか狐につままれた感じのするのは私だけでしょうか。

>・詳解C++(いわゆるAnnotated)を読んで、継承のメモリ利用
を勉強しろ

多分これが今の私に必要なんでしょうね。

はい。いろいろとがんばってみます。

皆様ありがとうございました。
152151:04/12/28 22:14:45
>結果:変わらないですね… 
コンパイル時間が変わっていると思うけど……
153デフォルトの名無しさん:04/12/29 01:08:18
mmap+boost で、データ構造のシリアライズがやりたいです。
具体的には、
1、データファイルをmmap で巨大なヒープとしてメモリに貼り付ける。
  なお、このとき、毎回同じメモリアドレスに貼り付ける必要性がある。
2、boost の new をいじくり、すべてそのmmapされたヒープの中でのみ
  allocate されるようにする。
以上で、データ構造がそっくりシリアライズできるような気がするのですが、
どうやってやればいいでしょうか。
154デフォルトの名無しさん:04/12/29 01:32:26
boost::serialize使えばいいのに
155デフォルトの名無しさん:04/12/29 01:33:17
boost::serializationだった
156デフォルトの名無しさん:04/12/29 03:49:42
ええっと、それだと、一度すべての変数をずるずるっと舐めることになりますよね。
そうじゃなく、効率も考え、変数空間全体をmmap でファイルに貼り付けたいんです。
157デフォルトの名無しさん:04/12/29 03:53:06
舐めるならレロレロとかチュパチュパじゃないか?
ずるずるってナニ?
158デフォルトの名無しさん:04/12/29 03:54:17
つーか
>毎回同じメモリアドレスに貼り付ける必要性がある。
これで破綻してるとは思わないのか
159デフォルトの名無しさん:04/12/29 05:06:16
それはすくなくともLinuxなら可能です。
とくに、今後の64bit Linuxなら、アドレス「空間」はいくらでも余ってるので、
何の問題もないでしょう。
160デフォルトの名無しさん:04/12/29 17:23:10
>>159
^^
161デフォルトの名無しさん:04/12/29 17:48:45
>>153
やりたいようにやればあ。
絶対アドレス依存じゃないヒープ保存で有名なのはEmacsとTeX。

絶対アドレスに依存するのはちょっと面倒だね。
C++のオブジェクトを直接張り付けるんじゃなくても、
wrapper classで仮想的に扱えるよね。
162デフォルトの名無しさん:04/12/29 21:34:37
おまえら、「boost の new」の意味はわかってるのか?
漏れにはわからん。
163デフォルトの名無しさん:04/12/29 21:39:05
「boostで使うnewとかもひっくるめて自分でglobalなoperator new()をオーバーライドしちゃいます」
という意味だと思ってた
164デフォルトの名無しさん:04/12/29 21:53:12
>>163
そうなると、「mmap+boost で」っていうのがわからん。
boost も template も関係ないじゃないか。
165デフォルトの名無しさん:04/12/29 21:58:22
ううむ。確かに。
boostの機能のキの字も使ってないもんなぁ。
166161:04/12/29 22:00:47
そもそもシリアライズじゃないし(w
167デフォルトの名無しさん:05/01/04 00:56:10
知り合いs
168デフォルトの名無しさん:05/01/06 00:15:21
GC(参照カウント方式)に使えるポインタオブジェクトで
オブジェクトのconst修飾が参照先のconst修飾に対応した
クラスってないでしょうか

Boost流だとこんな↓感じ?

template<typename T>
class my_shared_ptr : protected boost::shared_ptr<T>
{
public:
 const T * operator->() const { return __super::operator->(); }
 T * operator->() { return __super::operator->(); }

 // other functions implementation...
};

おねがいします
169デフォルトの名無しさん:05/01/06 00:22:41
>>168
そんな感じでいいんじゃないの?
170168:05/01/06 00:26:23
はい、ありがとうございます
ただ、既存のライブラリでいいのはないかと思いまして・・・
171デフォルトの名無しさん:05/01/06 01:16:46
>>170
Boost は「既存のライブラリ」以外の何だというのかね?
172デフォルトの名無しさん:05/01/06 02:12:11
>>168
ちなみにshared_ptr<T const>を嫌う理由は何ですか?
173デフォルトの名無しさん:05/01/06 06:31:17
重い
174デフォルトの名無しさん:05/01/06 10:28:20
プログラム全体の動作に致命的なほど遅くはなんねぇよ
175デフォルトの名無しさん:05/01/06 10:56:57
何の要件もなしに「重い」と言って切り捨てる >173 も、
何の前提もなしに「致命的なほど遅くはなんねぇ」という >174 も、
同じ程度に浅はかである。
176デフォルトの名無しさん:05/01/06 11:01:20
>>175
それを否定してしまったら何もかけなくなっちゃうよ。
177デフォルトの名無しさん:05/01/06 11:09:22
>>176
175が何を否定してるんだ?
178デフォルトの名無しさん:05/01/06 11:10:18
日本の将来
179電波系赤の他人:05/01/06 11:13:22
俺も人格も否定しているような気がする。
180デフォルトの名無しさん:05/01/06 18:37:00
>>172
嫌というほどでもないんですが、
コンパイルが遅そうとか、その程度です

const my_shared_ptr<T> get_obj_ptr() const;
my_shared_ptr<T> get_obj_ptr();

より、

shared_ptr<T const> get_obj_ptr() const;
shared_ptr<T> get_obj_ptr();

の方が意味的に適切だとは思うんですが

自分で書くのめんどうなので、とりあえずboost::shared_ptrでいいや・・・
181デフォルトの名無しさん:05/01/06 20:30:30
こういうのどうですか?

#defineBEGIN_JUNK( __Super, __Misc ) \
template< int _N >struct __Junkyard{ enum { _junk_no = __Junkyard< _N - 1 >::_junk_no }; }; \
template<> \
struct __Junkyard< __LINE__ > : public __Super::_junk \
{ \
enum { _junk_no = __LINE__ }; \
typedef __Super::_junk _prev; \
__Misc; \
}; \
typedef__Junkyard< __LINE__ >_start_junk; \

#defineREDEF_JUNK( __Misc ) \
template<> \
struct __Junkyard< __LINE__ > : public _prev_junk \
{ \
enum { _junk_no = __LINE__ }; \
typedef _prev_junk_prev; \
__Misc; \
}; \

#defineEND_JUNK() \
typedef_cur_junk_junk; \

長いので詳細は↓に書いてあります。
http://www2.odn.ne.jp/freelife/Junkyard.htm

割と使えると思うんだがどうだろう?
182デフォルトの名無しさん:05/01/06 22:08:44
>181
マクロで実装してるreflection系ライブラリの提案見るたびに思うんですけれど
マクロとテンプレートの相性の悪さはどう対処するつもりなんでしょうか?
毎回typedef?(面倒)BOOST_PP_SEQ?(カッコ悪い)variadic macro待ち?(いつ出る?)

struct Sample2
{
typedef Sample2 _self;
BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; );
DATA_MEMBER( 1, my_class<char, int>, x );
END_JUNK();
};
183181:05/01/06 22:39:57
>>182
言いたいことには同意
対処って程ではないが、苦肉の策でこんなことやってる

#define $ ,

struct Sample2
{
typedef Sample2 _self;
BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; );
DATA_MEMBER( 1, my_class<char $ int>, x );
END_JUNK();
};

はげしくかっこ悪いが w

184デフォルトの名無しさん:05/01/06 22:59:24
>183
それだとDATA_MEMBERが評価される前に$が評価されてしまうので結局同じことになりませんか?

色々漁ってみたら限界はあるもののいくつか対処法はあるみたいですね.
http://lists.boost.org/MailArchives/boost/msg46364.phpからだと

template<class T> struct wrap { typedef T type; };
template<class T> struct wrap<void (T)> { typedef T type; };
#define TYPE(x) wrap<void x>::type
#define DEP_TYPE(x) typename wrap<void x>::type

struct Sample2
{
typedef Sample2 _self;
BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; );
DATA_MEMBER( 1, TYPE((my_class<char, int>)), x );
END_JUNK();
};

とか.記事本文では指摘されていないですけれど,型がdependent typeか
どうかでマクロを使い分ける必要もありますね,これ.
・・・っていうか話題をそらしてしまってすいませんです.
185181:05/01/07 00:10:36
>>184
コンパイル通らないですか?
当方、VC++ 2003 しかないので、他のコンパイラだと通らないのだったら正直すまん
ただ、VC++ 2003 でも多重にマクロを定義している時は、評価順序によって通らない時もある
その時はマクロを調整するでは駄目ですか・・?

リンク先のようなやり方もあるとは知りませんでした
参考にさせて頂きます


186181:05/01/07 00:38:04
あと、typename に対してですが
__if_exists が使えればこういうやり方もあります

template< bool >struct ExistsBool {};
template<>struct ExistsBool< true > { enum { _true }; };

#defineTYPEDEF( __Type, __Alias ) \
__if_exists( __template__::_true ){ \
typedef typename __Type __Alias; \
} \
__if_not_exists( __template__::_true ){ \
typedef __Type __Alias; \
} \


template< class _Type >
struct Sample7
{
typedef ExistsBool< true >__template__;

TYPEDEF( _Type::_type, _type );

// 2値判定にも使える
__if_exists( ::ExistsBool< _Type::_n == 0 >::_true ){
}
};

__template__ をクラスごとに宣言する必要があるのが難点ですが
187デフォルトの名無しさん:05/01/07 19:48:15
>>184
>それだとDATA_MEMBERが評価される前に$が評価されてしまうので結局同じことになりませんか?
引数展開の前に引数は確定するから、この例では問題ない。
でもこの結果を別のマクロに渡すと結局だめだから、
あまりお勧めはできないが。

# define ID(x) x
# define COMMA() ,
# define DECL_A(type, var) type var
# define DECL_B(type, var) ID(type) var

DECL_A(std::pair<int COMMA() int>, pa); // ok
DECL_B(std::pair<int COMMA() int>, pb); // error: IDの引数過多
188184:05/01/07 21:39:12
>186
考えてみた結果enclosing scopeがtemplateかどうかに対する切り分けが
本質的に必要ではないかと思うのでこの方法はあまり使えなさそうです.

>187
マクロのargument substitutionについて理解が足りていませんでした.
function-like macroがidentityされてから後,replacement-listに対する
置換が実行される前にargumentに含まれるmacro tokenが置換されるんですね.
見た感じやはり184の解法が幾分かbetterでしょうか.
189181:05/01/08 00:55:07
これでどうだろう。>>184 と組み合わせてみた。

template<class T> struct wrap{ typedef T type; };
template<class T> struct wrap<void (T)>{ typedef T type; };
#define TYPE(x) wrap<void x>::type

template< bool >struct ExistsBool{};
template<>struct ExistsBool< true >{ enum { _true }; };

#defineTYPEDEF( type, alias ) \
__if_exists( __template__::_true ){ typedef typename TYPE((typename type)) alias; } \
__if_not_exists( __template__::_true ){ typedef TYPE((type)) alias; } \

#defineCLASS( __Class ) \
typedef __Classself; \
typedef ExistsBool< false >__template__; \

#defineTEMPLATE( __Class ) \
typedef __Classself; \
typedef ExistsBool< true >__template__; \

#define$,

190181:05/01/08 00:55:32
つづき

template< class T >
struct hara
{
TEMPLATE( hara );

template< class T > struct horo
{
TEMPLATE( horo );
TYPEDEF( T::type,type );
};
struct hire : public horo< T >
{
CLASS( hire );
TYPEDEF( my_class<char $ int>, type2 );
};

TYPEDEF( hire::type, type );
TYPEDEF( hire::type2, type2 );
};

$ を主張するわけではないが、タイプ量が少ないと嬉しいので
ところで、誰も Jankyard に触れてくれない orz
191デフォルトの名無しさん:05/01/08 01:04:10
誤: typedef __Classself;
正: typedef __Class self;
誤: #define$,
正: #define $ ,

です。連投すんまそん
192デフォルトの名無しさん:05/01/09 07:22:01
>ところで、誰も Jankyard に触れてくれない orz
ぶっちゃけていうとreflection系ライブラリの提案はすでに色々ありますからね.
自分の知っている範囲だと
http://www.garret.ru/~knizhnik/cppreflection/docs/reflect.html
http://www.arneadams.com/reflection_doku/index.html
あたりでしょうか?後プロパティの実装なら
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1615.pdf
とか.
ついでに__if_existsに関して,名前がするかどうかというコンパイル時の情報で
プリプロセッサレベルの処理を行えるというのは確かに強力で魅力的なんですが
やはりVC++限定なのがネックでしょうね.
一応クラスのメンバ(型・関数・変数)や非メンバ関数の存在をテストしてその情報を
コンパイル時に取得する技法を標準C++の範囲内で実装することは可能なので,
それでほとんどの部分は代用できると思います.
(というか自分は本質的に__if_existsが必要な状況を思い付けません)
193181:05/01/09 09:15:49
>>192
今回提案したのはリフレクション自体ではなく、その辺りをサポートする仕組みだったのだが。
リフレクションも含む、その他タイプリスト生成や、マクロ間での型の受け渡し、
継承関係の中で連番発行など。プロパティはネタです。

__if_exists は本質的に必要ないのには同意します。
ただ、テンプレートの特化の変わりに使えるので
__if_exists を使うとシンプルに記述出来ることも少なくありません。
この辺りは好みによるのでしょうね。
VC++限定なのはどうしようもないですが。

いづれにせよ、騒がしているだけのようなので、これで引っ込むことにします。

>一応クラスのメンバ(型・関数・変数)や非メンバ関数の存在をテストしてその情報を
>コンパイル時に取得する技法を標準C++の範囲内で実装することは可能なので,
>それでほとんどの部分は代用できると思います.
詳細きぼん
194デフォルトの名無しさん:05/01/09 12:47:08
ここでいいのかしら。ちょっと彷徨い気味ですがどうぞよろしゅう

2つのソート済みvectorの中で共通する項目の数を数えたいのですが
set_intersection( (省略) , common_ins)
common.size();
で実行しています。これだとvectorの中身が100kとかになった時に速度がちょっとまずいのです。
上記より高速な方法でなにか良案ご存知の方いらっしゃいませんか?
ちなみのその後、共通部分から作ったcommonに対する処理は何も行いません(数えたいだけです)
195デフォルトの名無しさん:05/01/09 12:52:27
vecAとvecBを
mergeしてvecCを作りuniqueしてvecA.size()+vecB.size()-vecC.size()
196デフォルトの名無しさん:05/01/09 12:54:20
set_intersectionもソート済み範囲なのか。なら>>194の方が遅そうだ。
197デフォルトの名無しさん:05/01/09 12:59:38
>>195のがだろ
198デフォルトの名無しさん:05/01/09 13:00:07
199194:05/01/09 13:14:44
mergeして差分を考える方法は実行済みなのですが
残念ながら、set_intersectionの方法に比べて倍近く時間がかかってしまったのです

う〜ん、これはもう構造的にどうしようもないですかね
割と頻繁に更新されるvectorなので、馬鹿にならないコストなんですが・・・
200デフォルトの名無しさん:05/01/09 13:29:34
スマートポインタを使ってるならただのポインタに変えてみる。
ただのポインタなら実体に変えてみる。
実体ならポインタに変えてみる。
201デフォルトの名無しさん:05/01/09 13:33:31
set_intersection の result は OutputIterator なので、
 *result = common (or *result++ = common)
がカウントアップの動作をするような擬似イテレータを作れば、
コピーのコストを無くすことができそうだ。
202デフォルトの名無しさん:05/01/09 13:39:05
うっ、そこを触ることになりますか…
Iteratorの中身について理解が出来ていないので全くの手探りになりますが、資料ひっくり返して勉強します
ありがとうございました
203デフォルトの名無しさん:05/01/09 14:48:42
暇つぶしにやってみた。
boost::counting_iterator がそのまま使えるかと思ったけど OutputIterator じゃなかった。
しょうがないから結局ファンクタ書く羽目になった。

#include <cstddef>
#include <algorithm>
#include "boost/function_output_iterator.hpp"

template<typename Incrementable>
class increment
{
  Incrementable* m_target; // not reference to make this class Assignable
public:
  increment(Incrementable& target) : m_target(&target) {}
  template<typename T> void operator () (T const&) { ++*m_target; }
};

template<typename InputIterator1, typename InputIterator2>
std::size_t count_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
{
  std::size_t result = 0;
  std::set_intersection(first1, last1, first2, last2
    , boost::make_function_output_iterator(increment<std::size_t>(result)));
  return result;
}

lambda 使えば、 increment くらい消せるかも。
204デフォルトの名無しさん:05/01/09 17:29:22
いちおうできた。

#include <cstddef>
#include <algorithm>
#include "boost/function_output_iterator.hpp"
#include "boost/lambda/lambda.hpp"

template<typename InputIterator1, typename InputIterator2>
std::size_t count_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
{
  std::size_t result = 0;
  std::set_intersection(first1, last1, first2, last2
    , boost::make_function_output_iterator(++boost::lambda::var(result)));
  return result;
}

ただ、 lambda のファンクタが Assignable にならないので、
_GLIBCXX_CONCEPT_CHECKS で怒られた。
VCでは /W3 まで大丈夫。
205デフォルトの名無しさん:05/01/09 19:25:21
template<class T>
struct X {
void func() {}
};

TがクラスAかクラスAのpublic派生クラスの特殊版を定義する場合
X<T>::func()をどのように定義すればよいのでしょうか?
206デフォルトの名無しさん:05/01/09 23:59:37
>193
具体的な実装の例だとboost/mpl/has_xxx.hppとかが参考になるかと思います.

>205
Boost使うなら以下のような感じでですかね?

#include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
struct A{ };
template<class T> struct X{
struct yes_tag{ };
struct no_tag{ };
typedef typename boost::mpl::if_<
boost::is_base_and_derived<A, T>, yes_tag, no_tag>::type
dispatch_tag;
void func_dispatch(yes_tag){std::cout << "derived version" << std::endl;}
void func_dispatch(no_tag){std::cout << "non-derived version" << std::endl;}
void func(){ func_dispatch(dispatch_tag()); }
};
struct Hoge : public A{ };
struct Huga{ };
int main(){
X<Hoge>().func();
X<Huga>().func();
}
207デフォルトの名無しさん:05/01/10 17:24:10
こういう書き方って動作は保証されるのでしょうか?

std::vector<int> test;

for ( std::vector<int>:iterator element = test.begin(); element != test.end(); element++ ) {
test.erase(element);
}
208デフォルトの名無しさん:05/01/10 17:30:51
↑おもいっきりぬけてたので修正しました

std::vector<int> test;

test.push_back(0);
test.push_back(1);
test.push_back(2);
test.push_back(3);
test.push_back(4);


for ( std::vector<int>:iterator element = test.begin(); element != test.end(); element++ ) {
if ( *element == 2 ) {
test.erase(element);
}
}
209デフォルトの名無しさん:05/01/10 17:35:21
>>208
eraseした時点でイテレータそのものが無効になるよ。
210デフォルトの名無しさん:05/01/10 17:38:08
ではループしつつ条件に当てはまるイテレータの内容だけ削除するには
どのような手段を用いればよいのでしょうか?
プールで一端どこかにマークをつけて、ループ終了後該当の物だけeraseとかでしょうか?
211デフォルトの名無しさん:05/01/10 17:38:33
だから、std::remove()で、値が2の要素をコンテナの後に集めておき、最後に一回だけ
eraseするといい。

test.erase(std::remove_if(test.begin(), test.end(), std::bind2nd(std::equal<int>(), 2)), test.end());
212デフォルトの名無しさん:05/01/10 17:38:57
あ、ループがプールに・・orz
213デフォルトの名無しさん:05/01/10 17:39:57
なるほど、ありがとうございます
214デフォルトの名無しさん:05/01/10 17:40:36
こういう書き方は最初は戸惑うかもしれないが、慣れるとすごく便利になる。
そのうちこれでも不便になって、必ずboost::bindとかに手を出したくなるから。
215デフォルトの名無しさん:05/01/10 17:43:26
わかりました。
参考にしてみます。
216デフォルトの名無しさん:05/01/10 17:43:57
というか、EffectiveSTLを読め。
>>211のも含めて色々書いてあるから
217デフォルトの名無しさん:05/01/10 17:50:47
test.erase(std::remove(test.begin(), test.end(), 2), test.end());
でもいいねこの場合。叙述関数あるいは関数オブジェクトの替わりにconstな値を
とるだけだから。
218デフォルトの名無しさん:05/01/10 17:58:23
if ( *element == 2 ) {
test.erase(element++);
}

でOK。
219デフォルトの名無しさん:05/01/10 18:01:18
>>218は忘れて。

for ( std::vector<int>:iterator element = test.begin(); element != test.end(); ) {
if ( *element == 2 ) {
element = test.erase(element);
}
else
++element;
}
220デフォルトの名無しさん:05/01/10 18:01:28
>test.erase(std::remove_if(test.begin(), test.end(), std::bind2nd(std::equal<int>(), 2)), test.end());

わけがわかりません。
こんなの仕事で使われたら恐怖です。
やめてください。
221デフォルトの名無しさん:05/01/10 18:02:08
>>217-219
やめてください。
怖いです。
222デフォルトの名無しさん:05/01/10 18:02:50
>>218
vectorコンテナのeraseはCで言うところのrealloc()に相当する動作を実行する
事もあるんだぞ。でたらめ書くな。
223デフォルトの名無しさん:05/01/10 18:03:47
>>220
そのくらいのSTL構文も分からないならC++使うのをやめた方がいいよ。
224デフォルトの名無しさん:05/01/10 18:06:37
>>222
おいおい。
「イテレータは、より小さなインデックスの要素が挿入または削除されたり、再割り当てが
行われて容量が変わるまで有効」だぞ。
規格票をよく読め。おまえこそでたらめ。
225デフォルトの名無しさん:05/01/10 18:10:44
規格票でました。

m9(^Д^)プギャー
226デフォルトの名無しさん:05/01/10 18:12:25
§23.1.2.8当たりだろ。
227デフォルトの名無しさん:05/01/10 18:13:13
http://www-6.ibm.com/jp/developerworks/linux/041203/j_l-cpregex.html
>言語の機能 であるはずのものが、その言語のユーザーを恐れさせるようになったら、何かを変えるべき時なのです。
228デフォルトの名無しさん:05/01/10 18:13:59
>>226
それAssociative Container
229デフォルトの名無しさん:05/01/10 18:15:05
ここは
問題を無闇に複雑にして悦に浸る馬鹿のス靴(なぜか変換できない)
ですね。
230デフォルトの名無しさん:05/01/10 18:19:30
§23.2.4.3当たりだと見た。
231デフォルトの名無しさん:05/01/10 18:20:25
>>227>>229
またperlとかrubyの○キ信者ですか?
232デフォルトの名無しさん:05/01/10 18:23:27
boostが異常なのは認めなければなるまい。
昨今のC++は異常が常態。
233デフォルトの名無しさん:05/01/10 18:24:29
確かに異常だが、使っているうちに快感になる。
234デフォルトの名無しさん:05/01/10 18:24:50
(23.1.1/7)と(23.2.4.3/3)読む限り>219でもOKっぽいですね
235デフォルトの名無しさん:05/01/10 18:27:46
CommonLispのようなわかりにくさを競い合って悦に浸るのがここの流儀
236デフォルトの名無しさん:05/01/10 18:28:39
>>234
OKだろ。個人的には俺はあまり書きたくないけど。
237デフォルトの名無しさん:05/01/11 00:57:13

>>219

引くってのはどうよ。

for(element = test.begin(); element != test.end(); ++it)
{
if(*element == 2){
test.erase(element--);
}
}

あ、でも element = test.begin(); element--; は大丈夫なのかな。

まぁ、EffectiveSTLを読んでいれば test.erase(remove(),test.end())と書くというのに一票。
238237:05/01/11 00:58:59
訂正。
>>237
++it => ++element

239デフォルトの名無しさん:05/01/11 01:06:22
>>237 ダメ
240デフォルトの名無しさん:05/01/11 14:28:58
for(element = test.begin(); element != test.end(); ++element)
if(*element == 2)
{
element = --test.erase(element);
}
こんな感じが一番シンプルなところなのかな?
241デフォルトの名無しさん:05/01/11 15:04:23
removeとeraseの組み合わせが一番シンプル
242デフォルトの名無しさん:05/01/11 15:59:47
とりあえずremoveとeraseの組み合わせが何でも一番です(^^
243デフォルトの名無しさん:05/01/11 16:01:18
clearって手もあるよ
244デフォルトの名無しさん:05/01/11 19:46:02
>>223
プロジェクトって大抵いろんな技術レベルの人がいるから
その台詞でばっさりはちょっと抵抗あるなぁ。
一人でやるなら何使ったってOKだけどね。
245デフォルトの名無しさん:05/01/11 20:32:55
>>244
211はかなり基本だと思うんだけど...
246デフォルトの名無しさん:05/01/11 20:46:56
あれが解からないって?


…ときどき思うんだ。俺、なんで2chなんか見てるんだろう、って。
247237:05/01/11 22:30:46
なんか不安になってきたので確認したいのですが
vectorのeraseで無効になるのは消した要素以降のイテレータですよね。
だから>>237>>240は結果的に同じことになりますよね?

私が>>237で心配だったのは

最初の要素でヒットしたとき、

element = test.begin();
--element;
++element;

でbegin()に戻るのが規格で保証されてなさそう(多くの実装では戻りそうだけど)
というのと

元々のサイズが1のとき、test.erase(test.begin());で全てのイテレータが無効になる
ときにバッファを解放してbegin()とend()がNULLを返してくるようになるとend()と
永遠に一致しなそう(VC7のclearがバッファを解放(capacityを0)にしてくれるのに
気づいて以来疑り深くなっています)

の二点なんですけど、
そのあたりをふまえて>>239はダメと言っているんですよね?

うーん、remove(や類似のアルゴリズム)を使わないでやるならやはり>>219なのか。
248237:05/01/11 22:34:15
ああ、そうか、後者の不安は>>240と書くことで払拭されるのか。
スマソ
249244:05/01/12 01:12:53
>>245
俺も基本だと思ってるし、これぐらいわかれよって思ってるよ。
でも、それが通用しないのが多人数でしょ?って投げかけ。
…技術と関係なくなるか。消えるよ。スレ汚しすまん。
250デフォルトの名無しさん:05/01/12 02:17:30
なぜforで回す……わざわざC++使うんだったら、効率にも気を
配らないともったいないよ。

>247
>237 >240の例だと
・ループごとにtest.end()の呼び出しが発生する
・elementを削除するたびにvectorの再パッケージが発生する
で遅くなりますな。

あと、>237だと後置インクリメントの一時オブジェクトの生成が
発生してさらに効率が悪くなります。
251デフォルトの名無しさん:05/01/12 02:18:18
なぜにremoveを使いたくないのかが知りたい
252250:05/01/12 02:24:13
自己フォロー

>237>240ともに、はelement==test.begin()のときに
*element==2だとアウトですな。

#test.begin()よりも前に移動するから未定義の世界に突入
253デフォルトの名無しさん:05/01/12 02:48:28
>250
ループごとのtest.end()も後置インクリメントもここでは本質じゃない。
254デフォルトの名無しさん:05/01/12 02:56:25
>253
ふうん、じゃ、こう言っておこうかな
・郷に入れば郷に従え
STLはC++の一部なんだから、それぐらい覚えろ
・こんぐらいできないなら、そもそもC++使うな
or こんなこともできないやつをプロジェクトに入れるな

他にもPerlとか色々あるんだから、わざわざC++を使う必要ないよね。
255デフォルトの名無しさん:05/01/12 07:36:48
list に追加されている remove(),remove_if() 見習って、
 template<class Container> void remove(Container&, typename Container::value_type const&)
 template<class Container, class Predicate> void remove_if(Container&, Predicate p);
のような関数を作れば、双方文句はなかろう。
256255:05/01/12 07:50:40
s/Container/Sequence/

remove() の意味が混乱を招きやすいという認識はSGIのドキュメントにも記載されている。
「慣用句だ」と言って押し切るよりは、むしろまともな認識だと思う。
http://www.sgi.com/tech/stl/remove_if.html#1

これをそのままソースに書いてしまうと言うのは、
例えば定数除算をシフトで書いてしまうのと同等の誤りであると思う。
257デフォルトの名無しさん:05/01/12 07:51:49

forで回すからうっかり>>218とか>>237とか>>240とかいう問題のあるコードを書いて
しまうんだよ。
だったらおとなしくremoveを使えと。

まぁ、色々書き方があってその中から適切な物を状況に応じて選ぶのがプログラムの
醍醐味ではあるけど。
258デフォルトの名無しさん:05/01/12 08:53:47
>なぜにremoveを使いたくないのかが知りたい
叙述関数やoperator==とかにコードが分散するのがイヤ
ループが内包されるのがイヤ ループを制御下に置いておきたい
ブレイクポイントが設定しやすいよ
削除以外の用途にループが流用できるよ

てゆうかぶっちゃけremove_copy中でやってること、あれはありえないでしょ
それを言ったらvectorでeraseすること自体ありえないかw
259デフォルトの名無しさん:05/01/12 09:59:55
>ループが内包されるのがイヤ ループを制御下に置いておきたい

ループを明示的に書くより効率が良くなる可能性があるし、
コードの見通しも良くなる
260デフォルトの名無しさん:05/01/12 10:06:05
>>254
「理想郷」との差でしかモノを語れない
頭でっかちの引き籠もりはレスしなくていいです ;-)
261デフォルトの名無しさん:05/01/12 10:32:21
>260
それ、オレじゃない。人違いだ
262デフォルトの名無しさん:05/01/12 10:48:33
>260
IDくらい見ろ、ボケ!
263デフォルトの名無しさん:05/01/12 11:10:58
>>262
この板ID無いんだって気付よ!
264デフォルトの名無しさん:05/01/12 11:21:54
お前さんたちなんか楽しそうだね。
265デフォルトの名無しさん:05/01/12 11:42:25
IDの見方知らない香具師ってまだいたんだね
266デフォルトの名無しさん:05/01/12 12:13:29
はっきりいってvectorに限らず配列っぽいデータ構造を使っている時に
removeみたいなアルゴリズムを適用したくなることってあるか?
無理して適用しておもしろいことがあるようなものでもないと思うのだけど…
何か見落としている革新的な理由でもあったりするのだろうか?
267デフォルトの名無しさん:05/01/12 23:55:01
> removeみたいなアルゴリズムを適用したくなることってあるか?

配列から複数の要素を一度に取り除きたいときだな。
268デフォルトの名無しさん:05/01/13 00:11:28
簡単
let remove x num = snd (List.partition (fun a -> a=x) num);;
269デフォルトの名無しさん:05/01/14 14:04:12
>>268
配列っぽくないデータ構造。
270デフォルトの名無しさん:05/01/15 01:33:25
>>267
そそ、端からeraseしてると効率悪いし、
効率的な処理にしようとすると意外に面倒。
271デフォルトの名無しさん:05/01/17 09:41:54
俺も小さくて、しかもあまり使わないような関数を分散させるのが嫌いなんだけど、
「リファクタリング」を読むと、一行処理すら場合によっては関数にすることを推奨してるんだよな。

しっかりした関数名をつけることによって可読性が高まるって話なんだけど、
必ずしもそうとは思えないのは、英語圏ネイティブじゃないせいかね。

と、templateスレに書き込もうとしたのだけど、主旨に合わないのでこっちに投棄
272デフォルトの名無しさん:05/01/17 09:43:01
C++スレに書くつもりが…
もうどうでもいいや
273デフォルトの名無しさん:05/01/17 13:41:34
リファ〜に書いてあるのは関数じゃなくてメソッドのことでは
何の分類もしない単独の関数増やしてくのはあんま良いとは思えないが
メソッドの場合インターフェース抽出とか階層整理とかで意味がある
274272:05/01/17 17:58:06
>>273
失礼、つい関数と呼んじまう。
インターフェース抽出や階層整理は、それ自体をメインにして行うべきな気がするんだよねぇ。

それどころかそれ以前で、非道い話だが「たくさんの、たった数行のメソッド」ってだけで、嫌悪感を感じてしまう。

いずれにせよスレ違い申し訳ない。
275デフォルトの名無しさん:05/01/18 00:41:35
>>273
そんな区別ないだろ。
少なくともC++ではthisポインタの有無しか違いはないわけで、
それが関数分けの基準に影響するとは思えない。
276デフォルトの名無しさん:05/01/18 01:35:22
時々272のような人いるよね。
読むときあっちこっちの関数みないといけないから、とか言って。

このヘタレが
277デフォルトの名無しさん:05/01/18 01:45:39
そもそも行数とか関係ないだろ
278デフォルトの名無しさん:05/01/18 02:41:33
>275
その他にも可視性とアクセス範囲に違いがあるわけで……
279デフォルトの名無しさん:05/01/18 08:17:20
>>278
そうだな。

それらが要るならクラス作ってメンバ関数を作ればいいし、
要らないならフリー関数にしてもいい。
どう整理するかどうかが違うだけで、
処理に名前をつけてまとめたほうがよいかどうかの基準には関係ない。
複数のフリー関数を作った後に、さらに
それらをまとめてクラスを作ればよいことに気付くことも考えられる。

思い立ったらさっさと名前付けてまとめれ。
渋る意味がわからん。
280272:05/01/18 08:20:53
ちとスレ違い悪いんでこっちでレス
http://pc5.2ch.net/test/read.cgi/tech/1099112338/41
281デフォルトの名無しさん:05/01/21 18:18:02
お聞きしたいのですが、
下記(次レス)のコードがVC7.1でコンパイルできませぬ。
どこがいけないのでしょうか…

色々実験してみた結果
・UINT を int にすると通る。
・UINT を std::size_t にしてもダメ。
・typename T を削除して、 boost::array の T を int とかにすると通る。
・boost:array の nSize を適当な数値で直打ちすると通る。
・bcc5.5.1 では普通に通る。
282281:05/01/21 18:18:34
#include <boost/array.hpp>
typedef unsigned int UINT;

template<typename T, UINT nSize>
class A
{
 typedef typename boost::array<T, nSize> tObjects;
 typedef typename tObjects::iterator    tObjectsIt;
 tObjects m_cObjects;

public:

 tObjectsIt Func();
};

// ↓C2244:関数の定義を既存の宣言と合致させることができませんでした。
template<typename T, UINT nSize>
inline typename A<T, nSize>::tObjectsIt A<T, nSize>::Func()
{
  return m_cObjects.begin();
}
283デフォルトの名無しさん:05/01/21 20:49:28
>>281
手元にVC7.1もboostもないし、よくわからんけど、
コンパイラがバグってることはよくあるからw
284デフォルトの名無しさん:05/01/21 20:57:34
>>282
g++(3.3.3)ではなんの警告もエラーもなく通るのぅ……
285デフォルトの名無しさん:05/01/21 21:31:52
>>282
戻り値を素直に
typename boost::array<T, nSize>::iterator
とすると通りますね。
286デフォルトの名無しさん:05/01/22 00:57:24
typedefがprivateなのにinlineなのがいけないんじゃないのか?
と試してもないのに言ってみる
287281:05/01/22 11:00:38
やはり、コンパイラが悪い方向なんですか… orz

なお、>>286を参考に、
すべてのメンバをpublic にしてみてもコンパイルが通りませんでした。


しょうがないので、現状では
・class内に直書き
>>285 の方法
の2点で回避したいと思います。

どうもありがとうございました。
288デフォルトの名無しさん:05/01/22 11:27:55
いまだにちゃんと動かないコンパイラ多いのかよ
おまえらC++信用できますか?
289デフォルトの名無しさん:05/01/22 11:28:34
C++なら信用できるよ。
290デフォルトの名無しさん:05/01/22 15:39:27
>>282
vc8 でもダメっぽい
291デフォルトの名無しさん:05/01/23 15:44:13
boost::bindはstd::bind2ndとかより実行速度が落ちるって本当ですか?
292デフォルトの名無しさん:05/01/23 16:18:47
>>291
ためして、みなさいって。
293デフォルトの名無しさん:05/01/23 16:20:48
using句が,による複数引数を受け付けないのは何故ですか?
using A::AA, A::AB, A::AC;
のように出来たら便利だと思うのですが?
294デフォルトの名無しさん:05/01/23 17:06:31
本スレの次スレ
【標準C++】C++相談室 part39【STL含む】
http://pc5.2ch.net/test/read.cgi/tech/1106466303/
295デフォルトの名無しさん:05/01/23 17:51:32
>>293
そんなんオレらに聞かれても困るよ
296デフォルトの名無しさん:05/01/23 17:57:05
>>293
プリプロセッサマクロを書くとか?
あんまり便利とも思えないけど
297デフォルトの名無しさん:05/01/23 22:42:53
boost(かSTL)に、次のような関数テンプレートって含まれていませんか?

template<typename T>
inline void assign(T& lhs, const T& rhs)
{
 lhs = rhs;
}

次のような感じで、setterを用意していないメンバ変数(m_is_foo)を変更する関数オブジェクトを作るのに使いたいのです。標準であるならそっちを使いたいなと思いまして。

hoge(boost::bind(assign<bool>, boost::ref(m_is_foo), true));

298デフォルトの名無しさん:05/01/23 23:01:05
>>297
試してないけど、 hoge(boost::lambda::var(m_is_foo) = true) じゃだめ?
299297:05/01/23 23:16:36
>>298
> 試してないけど、 hoge(boost::lambda::var(m_is_foo) = true) じゃだめ?
いけました。サンクスです。
うーん、lambdaか…。主観ですが実戦投入はちょっと怖いんですよね。
300デフォルトの名無しさん:05/02/07 09:18:51
ふぇ〜い
Boostを最新リリースにしたら@VC6
_bvector.hでコンパイラが内部エラー起こしてビルドできない
Releaseビルドなら通った
コンパイラもしょっちゅう固まるし
やっぱ テンプレートをプリコンパイルヘッダにしたのが悪いのかな ・・
301デフォルトの名無しさん:05/02/07 09:23:19
日記はMeadowにでm(ry
302デフォルトの名無しさん:05/02/07 09:28:51
>>300
ヘッダのインクルード順序を変えてみれ。
自分は面倒なので#ifとか使ってインクルード順序をすぐに変えられるようにしてる。
例:

#if 0 //ここを1にしたり0にしたりする。
#include <boost/regex.hpp>
#include <algorithm>
#else
#include <algorithm>
#include <boost/regex.hpp>
#endif


303デフォルトの名無しさん:05/02/07 14:42:53
Meta-Programming 専用のスレってない?
304デフォルトの名無しさん:05/02/07 17:41:03
あったけど、ここに統合。
305デフォルトの名無しさん:05/02/11 13:36:27
テンプレートを使ったクラスでundefined referenceがでます。
ソースは次のようなものです。プリプロセッサは省略してあります。

//temptest.h
template<class T> class temptest{
public:
    temptest();
};

//temptest.cpp
template<class T> temptest<T>::temptest(){}

//main.cpp
int main(){
    temptest<int> t;
    return 0;
}

gccでは "undefined reference to `temptest<int>::temptest(void)"
VisualC++6では "public: __thiscall temptest<int>::temptest<int>(void)は未解決です"
というエラーです。
ちなみに定義をインラインにしたらうまくできました。
どなたか解決方法を教えてください。
306デフォルトの名無しさん:05/02/11 13:40:12
>>305
templateの定義はヘッダに書かないとダメ、ということになってます。
307304:05/02/11 13:50:47
そんな決まりがあったんですか。
でもSTLのインクルードファイルを見たところ宣言だけのようですが、
STLは特別なんでしょうか。
308デフォルトの名無しさん:05/02/11 13:52:15
STLもヘッダの下のほうに書いてあるんじゃねーの
309デフォルトの名無しさん:05/02/11 13:52:42
STLも例外ではないよ
クラステンプレートに実体がなくてもその後ろにクラスメンバのテンプレートの実体が定義されてるはず
310デフォルトの名無しさん:05/02/11 14:13:29
stlportだとcppをヘッダからincludeしてたとおもう
311デフォルトの名無しさん:05/02/11 14:44:21
ヘッダからcppをインクルード・・・萌えるな。
312デフォルトの名無しさん:05/02/11 15:04:53
>>307
  temptest.cpp コンパイル時には class T が何だか解らないので
  コンストラクタは生成されない
    ↓
  main.cpp コンパイル時には temptest<int> のコンストラクタが
  どこかにあるものとしてコンパイル
    ↓
  リンクしてみたら、どこにもいない

明示的にインスタンス化するよろし。

//temptest.cpp
template class temptest<int>;
313デフォルトの名無しさん:05/02/11 16:01:01
exportキーワードをまともに実装した処理系はComeau C++だけでしょ。
314デフォルトの名無しさん:05/02/11 19:41:42
もう諦めてexportを標準から外した方が良いんじゃないかとさえ思ったり.
現状,exportによる利得というのがほとんど無いみたいですし.
315デフォルトの名無しさん:05/02/11 21:11:04
つーか既に実装しなくていいよもう、ってことになったんじゃなかったか?
316デフォルトの名無しさん:05/02/11 21:50:10
>315
ソースきぼんぬ.
export周りは泣きそうなほどグダグダみたいですし,さもありなんですけど.
317デフォルトの名無しさん:05/02/11 22:10:19
それがC++クオリティ
318デフォルトの名無しさん:05/02/12 06:49:19
>>316
D&E日本語版読んでみ。
exportは未だに実装してないといけない規格になっている。
319デフォルトの名無しさん:05/02/12 19:42:14
exportって何?
320デフォルトの名無しさん:05/02/12 19:42:57
るby
321デフォルトの名無しさん:05/02/16 10:47:32
shared_ptrとかintrusive_ptrのリファレンスカウント操作って
引数で値渡しすると呼び出しのたびに操作しますよね。
最適化によるコード削減を阻害しないでしょうか?
特にテンプレートを展開したもののコードがどうなるかが気になります。

322デフォルトの名無しさん:05/02/16 11:26:01
>>321
適材適所で。
それからテンプレートの勉強もね。
323デフォルトの名無しさん:05/02/16 11:38:00
>>322 要するにオーバーヘッドはかかるというお答えという理解でよろしい?

intrusive_ptrの参照を渡せばいいんですけど、ポインタの置き換えに使うつもり
でいるといまひとつ面倒というか泥くさいというか。
あと、これらのコンテナをfor_eachなどで処理するときのbind(+lambda)で、
_1 と書くだけじゃdeductionしてくれず、bind(&HogePtr::get, _1)
のようにしないといけないのが面倒で、
これを何とか自動でやってくれるようにする方法はありませんか。

HogePtrという派生クラスを作ってポインタから暗黙的にキャストさせると
一番簡単にコンパイラを黙らせられるんですが、今度はコンテナを処理するときに
毎回HogePtrを作って比較するというコードを出してくるようになるので、
なるべく派生はさせずに済ませたい。
324デフォルトの名無しさん:05/02/16 20:11:57
参照カウンタによるオーバーヘッドが許せないのなら、
shared_ptr系は精神衛生上使わないほうがいいと思う。
325デフォルトの名無しさん:05/02/17 00:41:46
>>323
bind の件は既に修正済みのはず。
326デフォルトの名無しさん:05/02/17 14:17:53
>>323
恐ろしいことだが君のようなハッカーには
それらはもうレガシーだ。boostなのにね。
sandboxにModern C++ Designのを移植した
policy_ptrというのがあるので見るべき
これはなかなか強烈だよ
327デフォルトの名無しさん:05/02/18 02:14:48
>>326
お前は独逸の詩人かよ!?
328デフォルトの名無しさん:05/02/18 12:12:10
>>326
ポリシーベースの派、前に検討して却下してshared_ptr達が採用されたのに
なんで今更?
329デフォルトの名無しさん:05/02/18 20:40:47
>328
その議論読んでみたいんですがどこにありますか?

policy_ptrは「shared_ptrは重い」といった主張を持つユーザに対する
選択肢の一つとして提供されるのだと思いますよ.
そもそもpolicy_ptrはshared_ptrなどの既存のスマートポインタに取って代わるものではなく,
むしろそれらと相補関係にあって共存するべきものですし.
なのでshared_ptrを"legacy"と表現するのは恐らく適切ではないです.
ここら辺のもう少し詳しい議論は以下のスレッドや
policy_ptrのドキュメントのFAQあたりが参考になると思います.

http://thread.gmane.org/gmane.comp.lib.boost.devel/116983
330デフォルトの名無しさん:05/02/18 21:19:44
似たような*_ptrばっか増やして、
馬鹿じゃないの?
ふざけてるの?
331328:05/02/18 21:23:27
332デフォルトの名無しさん:05/02/18 23:38:55
>>330
C++ ってそういうもんだよ。人によって用途も違えば、実行環境のリッチさも
天と地ほど違うので。
333デフォルトの名無しさん:05/02/22 15:00:52
新規にクラスを作るならば、COM のように侵入型の参照ポインタにして、
intrusive_ptr で管理するとか
334デフォルトの名無しさん:05/02/22 17:27:12
STLかboostあたりに、ある条件を満たすものをoutput_iteratorにコピー
するような関数はないでしょうか?
boost::mplにcopy_ifというそれらしい名前のがあるんですが、
使い方がさっぱりわからない……
335デフォルトの名無しさん:05/02/22 17:40:29
なぜか std に copy_if ないんだよね・・・
boost::filter_iterator と std::copy でなんとか汁
336デフォルトの名無しさん:05/02/22 17:43:19
std::remove_copy_if(first, last, std::not1(pred));
337336:05/02/22 17:43:58
ごめん。
std::remove_copy_if(first, last, out, std::not1(pred);
だ。
338デフォルトの名無しさん:05/02/22 18:06:02
今回は元のコンテナを変更したくないのでremove_copy_ifは使えなさそうです。
結局自分で書きました。
自分でforループを書くと頭悪くなったように感じるので、
これくらいstdに入れておいてほしいものです……。

template <class InputIterator, class UnaryFunction, class OutputIterator>
void copy_if(InputIterator begin, InputIterator end,
             OutputIterator result,
             UnaryFunction pred) {
    for ( ; begin != end; ++begin)
        if (pred(*begin)) {
            *result = *begin;
            ++result;
        }
}

g++のヘッダを見るとconcept checkとやらを入れたほうがいいらしいのですが、
何を使えばいいのかよくわからんです。boostに道具があるんでしょうか。

remove_copy_ifも説明がよくわからんのですよね。
削除するのに大きさが変わらないってどういうこと?
339デフォルトの名無しさん:05/02/22 18:06:58
>>338
remove_copy_ifは入力シーケンスを変更しないよ。
340デフォルトの名無しさん:05/02/22 18:17:58
>>338
return result;
341一つ賢くなった!:05/02/22 18:32:43
>>339
おお、本当だ。コードを見るとほぼそっくりではないですか。
今までremove_copy_ifは元のを破壊的に変更しつつ、削除したものを
コピーするのだと思っておりました。
名前がミスリーディングだと思うのです……。

>>340
忘れてました。というか気にしてなかったのですが、返すべきですね。
342デフォルトの名無しさん:05/02/22 19:24:56
struct NURUPO
{
 template<typename T> operator T*() { return 0; }
};

int ILoveNurupo()
{
 NURUPO mynurupo;
 return (int)mynurupo[0];
}

vc7.1とgcc3.3にガッ
343デフォルトの名無しさん:05/02/22 21:10:19
なんか違わないか?
344デフォルトの名無しさん:05/02/23 01:38:28
>>338
STLPortには入ってるよ。
345デフォルトの名無しさん:05/02/24 14:00:35
テンプレートの特殊化ってどこに書きますか?
以下のように特殊化する型の定義と一緒に書くと、

* primary.h

#include <iostream>

template <class T>
inline void foo(const T&) { std::cout << "primary\n"; }

---
* specialized.h

#include "primary.h"

struct bar {};

template <>
inline void foo(const bar&) { std::cout << "specialized\n"; }

---
* troublesome.h

struct bar;

bar& get_bar();
346345:05/02/24 14:01:58
* troublesome.cpp

#include "specialized.h"

bar& get_bar() { static bar b; return b; }

void trouble1()
{
 foo(get_bar());  // #1
}

---
* main.cpp

#include "primary.h"
#include "specialized.h"  // #2
#include "troublesome.h"

int main()
{
 foo(get_bar());
 return 0;
}

---

#1 と #2 をコメントアウトしたりしなかったりで実行結果が変化します。
具体的には #1 と #2 の両方をコメントアウトした場合 primary が出力されます。

かといって、極端な話 STL のヘッダファイルに書き足すわけにもいけませんし・・・。
347デフォルトの名無しさん:05/02/25 00:39:40
>>345
ttp://www.kuzbass.ru/docs/isocpp/template.html#temp.expl.spec
14.7.3 -6- および -7- で、
使う場所より前に特殊化は宣言されていないといけない、
というルールは書いてあるが、コンパイラによるチェックは不要ということになっている。
あげくに規格中に「宣言の位置には気をつけろ」と書かれている。

primary.h の foo<T> の中でダミーでいいから sizoef(T) を使って、
不完全型ではインスタンス化できないようにしておけば、
いちおうエラーにすることができると思う。
348デフォルトの名無しさん:05/02/28 11:44:49
template<class T> class A
{
public:
void hoge() { }
void foo() { }
// 他にいろいろなメンバがある
};

というクラステンプレートがあって、プログラム中でA<T>::hogeだけどこからも使われなかったとき
A<T>::hogeのコードは生成されるのでしょうか?
349デフォルトの名無しさん:05/02/28 12:01:34
>>348
されない。だから定義しなくても大丈夫。
350デフォルトの名無しさん:05/02/28 19:22:11
>>348
処理系依存
351デフォルトの名無しさん:05/02/28 21:47:50
>>350
ほんと?
352デフォルトの名無しさん:05/02/28 22:10:33
一応標準としてはAの暗黙のインスタンス化ではhogeはインスタンス化されません.(14.7.1/1)
ちなみにAの明示的インスタンス化の際にはhogeのインスタンス化が伴います.(14.7.2/7)
353デフォルトの名無しさん:05/02/28 22:10:41
>350は狼少年
354デフォルトの名無しさん:05/03/01 22:32:51
>>348
Modarn C++ Designの1.8に、生成されないことを前提にした技法があったな確か。
シンタックス・チェックだけは、実装によっては行われるんだったっけか。
355デフォルトの名無しさん:05/03/02 01:29:19
Modern ね
356デフォルトの名無しさん:05/03/02 12:31:04
スマソ
357デフォルトの名無しさん:05/03/08 02:55:11
AdobeのASLもここでいいんかな?
358デフォルトの名無しさん:05/03/08 10:23:35
使われているプログラミング技法を語るならここかな
あるいはBoostスレか
359デフォルトの名無しさん:05/03/09 18:17:53
以下のコードで complex を set に入れようとしたところ、
「stl_function.h:197: error: no match for 'operator<' in '__x < __y'」
とか言われてしまうのですが (g++ 3.3.3)、原因が分かりません。
何がおかしいのでしょうか。

#include <complex>
#include <set>
using namespace std;

bool operator<(const complex<int> &a, const complex<int> &b)
{
return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b));
}

int main()
{
set<complex<int> > s;
s.insert(complex<int>(1, 2));
return 0;
}
360デフォルトの名無しさん:05/03/09 18:39:00
>>359
<set>の中からそのoperator<()が見えていない。しかしoperator<()を
#includeよりも前に持ってくると今度はcomplexが定義されていない。
しかしstd名前空間内部のものを先行宣言することは許されていない。

自分で関数オブジェクトを定義するしかない。
361デフォルトの名無しさん:05/03/09 18:40:16
namespace std {
  bool operator<(const complex<int> &a, const complex<int> &b)
  {
      return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b));
  }
}
で通ったけど、これってやっていいことだっけ……?
362デフォルトの名無しさん:05/03/09 18:56:02
>>360
> <set>の中からそのoperator<()が見えていない。
これは関係ない。どうせグローバルのoperator<は使われない。
363デフォルトの名無しさん:05/03/09 19:00:21
>>361
結論:ダメ
宣言や定義をstd名前空間に加えてはならない。今回の場合、struct
std::less<>の特殊化も考えられるが、後述の規定によりuser-definedな名前で
特殊化しない限りundefined behaviorとなる。

17.4.3.1 Reserved names -1
It is undefined for a C++ program to add declarations or definitions
to namespace std or namespaces within namespace std unless otherwise
specified. A program may add template specializations for any standard
library template to namespace std. Such a specialization (complete or partial)
of a standard library template results in undefined behavior unless
the declaration depends on a user-defined name of external linkage
and unless unless the specialization meets the standard library requirements
for the original template.
364デフォルトの名無しさん:05/03/09 19:17:37
>>362
#include <set>
using namespace std;
struct hoge{int x;};
bool operator<(const hoge& a, const hoge& b){return a.x < b.x;}
int main(){
    set<hoge> s;
    s.insert(hoge());
    return 0;
}
これ通らない?
365デフォルトの名無しさん:05/03/09 21:08:49
>364
それはhogeとoperator<が同じ名前空間(グローバル)で定義されているので通りますよ.
std::complexを引数とする呼び出しからoperator<が見えるためには
operator<がstd名前空間で定義されていないといけないです.
でもそのような定義をstd名前空間に追加することは許されないので(>363),
自分で関数オブジェクトを書いて(>360)それをsetのテンプレート引数に与えるしかないです.
366デフォルトの名無しさん:05/03/09 21:12:46
で、結局こう、と。

#include <complex>
#include <set>
using namespace std;

template <typename T>
struct complex_less: binary_function<complex<T>, complex<T>, bool> {
  bool operator() (const complex<T>& a, const complex<T>& b) {
    return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b));
  }
};

int main () {
  set< complex<int>, complex_less<int> > s;
  s.insert(complex<int>(1, 2));
  return 0;
}
367359:05/03/09 21:25:39
>>360-366
皆さんありがとうございます。よく分かりました。
ちゃんと勉強しないとダメだなぁ〜 orz
368デフォルトの名無しさん:05/03/09 21:55:23
string とか pair が std 名前空間に operator < を定義しているから
ADL のせいで operator < を std 名前空間の外に探しに行かないという認識であってますか?
369デフォルトの名無しさん:05/03/09 22:09:23
↑俺には断言できん


↓あってるのか?
370デフォルトの名無しさん:05/03/09 22:11:50
あってる。
371369:05/03/09 23:24:46
>>368
あってるぞ。

よし、俺ツーポイントゲット。
372デフォルトの名無しさん:05/03/10 04:08:30
その為に less がテンプレート引数になってるんではないのか。

…と、こないだ初めて map で less を使った俺が言いました。
373デフォルトの名無しさん:05/03/11 02:09:30
練習で push_back_if なるものを書いてみたのですが
駄目だしお願いします。

template <typename IIte, typename Container, typename Pred>
void push_back_if(IIte b, IIte e, Container &c, const Pred p)
{
for(;b!=e;b++)
{
if(p(*b)) c.push_back(*b);
}
}

insert_if とか copy_if ってないんですか?
あったら便利だと思うのですが・・・。
374デフォルトの名無しさん:05/03/11 02:24:34
copy_ifはある。あとはback_inserterを組み合わせて使えばよし。
375デフォルトの名無しさん:05/03/11 02:27:17
> copy_ifはある。

ウソだった。標準ではない。すまん。



376デフォルトの名無しさん:05/03/11 02:36:13
>>373
残念ながらcopy_ifは標準にはない。どっかに作っておいたら?
//copy_if
template <typename InputIterator,
          typename OutputIterator,
          typename Predicate>
inline
OutputIterator
copy_if(InputIterator  begin,
        InputIterator  end,
        OutputIterator destBegin,
        Predicate      p)
{
    while (begin != end)
    {
        if (p(*begin)) *destBegin = *begin;
        ++destBegin;
        ++begin;
    }
    return destBegin;
}
377デフォルトの名無しさん:05/03/11 16:52:41
>>373
> for(;b!=e;b++)
++bにしたほうがいい。
378デフォルトの名無しさん:05/03/11 19:43:05
>377
また荒れるようなことを
379デフォルトの名無しさん:05/03/11 20:28:43
いやいや荒れるまでもなく当たり前の事ですよ
380373:05/03/11 21:26:10
>>374-379
レスが遅くなってすいません。参考にします。
381デフォルトの名無しさん:05/03/13 00:46:27
荒れてもいいから理由を教えろ
382デフォルトの名無しさん:05/03/13 01:27:48
>>381
後置インクリメントだと、一時オブジェクトが必要になるから。
POD型の場合でもレジスタを余計に必要としたりね。
#それが理由で後置インクリメントを持たないクラスも作ることも多いし。
383デフォルトの名無しさん:05/03/13 01:32:28
C++より++C
384デフォルトの名無しさん:05/03/13 01:50:07
> POD型の場合でもレジスタを余計に必要としたりね。

は?
385デフォルトの名無しさん:05/03/13 03:26:57
今 typeof が使えるコンパイラって g++, icc の他にどんなのがある?
typeofなんてぶっちゃけ template つかってないと殆ど使わんだろうしここでいいよね。
386デフォルトの名無しさん:05/03/13 09:54:26
RTTIとテンプレートはあまり関係ないだろうと思いつつ、
ほとんどのメジャーなコンパイラは扱えますよ。
387デフォルトの名無しさん:05/03/13 09:57:05
typeidじゃないよ。
388デフォルトの名無しさん:05/03/13 12:31:23
メジャーじゃないコンパイラは"ほとんど"に含まれない言葉のトリック
389デフォルトの名無しさん:05/03/13 13:47:16
そういうもんだいではない
390デフォルトの名無しさん:05/03/13 17:59:47
#define FOR_EACH(RANGE, ITERATOR) \\
for(boost::range_iterator::< typeof(RANGE) >::type ITERATOR \\
      = boost::begin(RANGE); \\
    ITERATOR != boost::end(RANGE); \\
    ++ITERATOR)

int a[3] = {1, 2, 3};
FOR_EACH(a, it){
  cout << *it << endl;
}
391デフォルトの名無しさん:05/03/13 18:00:22
struct plus
{
  template<class LHS, class RHS>
  typeof(l + r) operator()(LHS const &lhs, RHS const &rhs) const{
    return lhs + rhs;
  }

private:
  LHS l;
  RHS r;
};
392デフォルトの名無しさん:05/03/13 18:15:58
391間違えました.スレ汚してすいません

template<LHS, RHS>
struct plus_result{
  typedef typeof(l + r) type;
private:
  LHS l;
  RHS r;
};

struct plus
{
  template<class LHS, class RHS>
  typename plus_result<LHS, RHS>::type operator()(
    LHS const &lhs, RHS const &rhs) const
  { return lhs + rhs; }
};
393デフォルトの名無しさん:05/03/13 18:17:47
typeof って何で標準に入る予定ないの?
394デフォルトの名無しさん:05/03/13 18:21:14
最初からplus_resultのとこにtypeofを書けばいいような?
395デフォルトの名無しさん:05/03/13 20:16:10
>>393
そんなこと誰が言ったんだ?
396デフォルトの名無しさん:05/03/13 22:50:55
条件Aに適合する場合にBを適用するという意味で
apply_if を書いてみたのですが、駄目だしをお願いします。

  template <typename IIte, typename CheckPred, typename ApplyPred>
    void apply_if(IIte begin, IIte end, CheckPred check, ApplyPred apply)
  {
    for(;begin!=end;++begin)
    {
      if(check(*begin)) apply(*begin);
    }
  }
397デフォルトの名無しさん:05/03/13 23:18:26
>>396
じゃ遠慮なく。
・名前の省略するな。(×IIte → ○InputIterator)
・Pred は predicate(述語) の略なので、 bool を返す関数以外には使うな。(×ApplyPred → ○UnaryFunction)
・*begin が繰り返されているのは良くない。
・std::for_each() に倣って UnaryFunction を戻り値としたほうがいいかもしれない。
398デフォルトの名無しさん:05/03/14 00:29:28
>>397
細かいことを言えば、
InputIterator に apply はまずい。
InputOutputIterator じゃ長いけど。
399デフォルトの名無しさん:05/03/14 01:03:01
とりあえず試しに Visual C++ Toolkit 2003 を使ってみたけど、
typeof() は使えない模様。__typeof とかなんかあったりするのかな?
400デフォルトの名無しさん:05/03/14 01:06:34
>>398
イテレータのコンセプトを表すという意味で InputOutputIterator はありえない。
出力も兼ねると言うことなら、現行の規格では ForwardIterator が候補になるだろう。
しかしここも std::for_each() に倣って InputIterator とするのが正解だろう。
401デフォルトの名無しさん:05/03/14 01:13:19
なんなんだよ、typeof()って?
初めて聞いたぞ。

type_infoクラスとtypeid演算子ならC++にあるけど、
typeof()は何をするためのもの?
402デフォルトの名無しさん:05/03/14 01:21:18
>>401
まず最初に言っておくと、typeofは今のところまだ標準には無い。
で、まぁ名前の如く変数の型を得る演算子(?)の事。
Type a;
typeof(a) b = a;
みたいに使える。
この例では a の型が分かってるけど、Expression Template なんかの場合はどえらい事になっちゃうっしょ。
って分かりにくいかなぁ。誰か分かりやすい例キボンヌ。
403デフォルトの名無しさん:05/03/14 01:27:44
その程度だとtypeid, type_infoとどう使い方が違うのか見えんな。
404デフォルトの名無しさん:05/03/14 01:29:18
テンプレート宣言の
template<typename HOGE>
を適宜、
template<typename HOGE, typename PLUS_TYPE>
にすれば回避できるんじゃないの?
曖昧さの解決にもなるし。

というか、C++とtypeof()は相性が最悪な気がする。
多重継承さえ嫌がる人が多いというのに、
typeof()は、無駄にデバッグ作業を増やさせるだけではないか?
405デフォルトの名無しさん:05/03/14 01:31:35
>>400
ForwardIteratorが正しいね。
しかし、InputIterator で要素の変更を行うのは論外では?
for_each()は変更を伴わない関数。
本質的に違う関数に倣うという理由付けも理解に苦しむ。
406デフォルトの名無しさん:05/03/14 02:01:52
>>405
std::for_each() で要素の変更は許される方向にあるらしい。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#475

「いまさら禁止されては困る」という本音が多分にあるだろうと思うので、
明示的に許可を後付けされてもすっきりしないよな。
はっきりと Mutating algorithm に移動させて欲しい。
407デフォルトの名無しさん:05/03/14 08:46:06
>>403
オマエの目は節穴なのでしょうか?
408402:05/03/14 11:23:16
>>403
うーん、例が悪いでしょうかねぇ。ただ、typeidと決定的に違うのが、
「コンパイルタイムに決まる」、という事。
んだから、「謎の型を宣言、定義可能」って事なんですけどね。
明日から海外飛ぶんで誰かフォローよろ。
409デフォルトの名無しさん:05/03/14 12:32:23
俺も来週から地方飛ばされるんで
誰か助けてくれ
410デフォルトの名無しさん:05/03/14 12:37:00
俺はneetなんである意味助けてくれ
411デフォルトの名無しさん:05/03/14 12:37:50
>>408,409
そのままキャッチされない例外に飛ばされて人生の強制終了。
412デフォルトの名無しさん:05/03/14 12:43:12
C++よりMLの方がいいよ。
413デフォルトの名無しさん:05/03/14 12:45:00
メーリングリスト
414396:05/03/14 23:32:14
>>397,398,400,401,405,406
参考にしたいと思います。ありがとうございます。
415デフォルトの名無しさん:05/03/15 00:04:29
C++よりMLの方がいいよ。
416デフォルトの名無しさん:05/03/15 00:16:03
>>412
>>415
利点をあげてくれ、なにがいいのかわからん
417デフォルトの名無しさん:05/03/15 00:47:28
このスレが不要になるぐらい明快
418デフォルトの名無しさん:05/03/16 07:47:07
そうか、typeofはgccとintel以外じゃ使えないのか。

クラス階層のメンバを辿るときとか便利なんだよな。
node->get_parent()->get_view() とかで参照をとるとき、一回だけだと
その場に書くけど長いと面倒なので何か別名を割り当てるためだけに
ローカル変数に代入するわけだ。
そういうとき、
#define LET(var,exp) typeof(exp) var = (exp)
とかすると
VeryVeryLongClassName parent_view = node->get_parent()->get_view();
のかわりに
LET(panent_view, node->get_parent()->get_view());
と書ける。非常にラクチン。

boostのlambdaみたいにすればtypeofなしでも同じようなことができるかも。
419デフォルトの名無しさん:05/03/16 08:08:57
>>418
boost spirit typeof

420418:05/03/16 09:26:00
どうもboostの定義をみてるとMetrowerksにもtypeofがあるようだ。
んで、typeofのテンプレートによる実装もあるみたいだね。

http://aspn.activestate.com/ASPN/Mail/Message/boost/2504137
boostのsandboxにtypeofの実装があるらしい

http://aspn.activestate.com/ASPN/Mail/Message/boost/2504137
Code Projectの記事。typeofのVC7用実装。
これによるとboost::mplにも

BOOST_MPL_AUX_REGISTER_TYPE(123, abc);
abc aa1;
BOOST_MPL_AUX_TYPEOF(_, aa1) *aa2 = &aa1;

というtypeofがあるらしいがundocumentedだのuglyだの不便だのと切って捨てている。

>>419
? よくわからんちん。
421デフォルトの名無しさん:05/03/16 15:39:09
>>420
http://boost.cppll.jp/HEAD/libs/spirit/doc/subrules.html

typeofはレビュー待ちの状態だと以前読んだ希ガス
422デフォルトの名無しさん:05/03/16 16:23:33
>>420
Metrowerks CodeWarriorでの話。
__typeof__()演算子があって、これは常に使える。typeof()演算子を使うには
#pragma gcc_extensions onとする必要がある。こうすると、以下のGNU Cの言語
拡張機能を利用します。
・auto変数の構造体、または配列を、定数以外の値で初期化することを許可します。
・sizeof( void ) == 1
・sizeof( function-type ) == 1
・評価式の内部のGCCステートメントと宣言を、制限付きでサポートします。
・#undefがその前にないマクロの再定義。
・GCCのtypeofキーワード。
423デフォルトの名無しさん:05/03/17 09:40:37
>418
>boostのlambdaみたいにすればtypeofなしでも同じようなことができるかも。
逆だと思いますよ.lambdaも状況は似たようなもので
むしろlambdaもtypeofがあればいろいろうれしいです.

でもboostのtypeofの実装はさすがにやりすぎな気が・・・
そもそもtypeofの機能をライブラリで提供する/できるというのが異常というか
424418:05/03/17 10:10:08
420のCode Projectの方のリンクが寝惚けてました^^; 正しいのはこっち。
http://www.codeproject.com/vcpp/stl/typeof.asp

>>421
すいません、あいかわらずよくわかりません。subruleが普通のコードでも使え
るってこと? 数字を手で入れる必要があるのは面倒なような……。

>>422
補足サンクスです。そうそう、__typeof__でした。
そうか、MetrowerksはGCC拡張を一部サポートするんですね。
425デフォルトの名無しさん:2005/03/25(金) 00:52:31
gcc 3.4のバグだろうか。
テンプレート関数の中で

boost::mpl::identity<typeof(foo->get_bar())>::type bar;

と変数を定義しようとすると何故か
expected `;' before "bar"
というエラーになる。

普通の関数の中なら問題なく通るのだけど。
426デフォルトの名無しさん:2005/03/25(金) 00:58:26
>>425 typname
427デフォルトの名無しさん:2005/03/25(金) 02:26:51
>>426
サンクス。
typenameは試したはずなんだけど……と思いつつやってみると
コンパイル通りました。吊ってきます。
428デフォルトの名無しさん:2005/03/30(水) 01:09:51
Boost.Serialization の
#include <boost/serialization/shared_ptr.hpp>
にある
#define private public
#include <boost/shared_ptr.hpp>
#undef private
って、shared_ptr の方を変更してもらえないんですかね?

別のスレッドで Boost.Serialization を教えてもらったんですけど、
これが、ちょっと気になります……。
429デフォルトの名無しさん:2005/03/30(水) 01:17:26
変更して貰えるわけないだろ、氏ね(ここまで一筆書き)
430428:2005/03/30(水) 02:21:20
>>429
Boost 同士ということで friend にしてもらうくらいなら、
と思ったんですが、直接には関係しない物のために変更するのは、
やっぱり無理ですよね。
431デフォルトの名無しさん:2005/03/30(水) 04:00:47
そういうのはここで訊くよりboostのメーリングリストを検索した方がいいのでは。
432428:2005/03/30(水) 05:05:42
>>431
読んでも分からなさそうと言う事で避けてました。すみません。

で、検索してみたら、そのままの議論がありました。
が、やっぱり分かりませんでした。orz

ただ使うだけにします。ありがとうございました。
433デフォルトの名無しさん:2005/03/30(水) 05:40:36
そういう場合はスレッドのURLとか貼っておくといいかもね。
434デフォルトの名無しさん:2005/03/30(水) 13:22:32
Serializetionがオブジェクトを覗き見しなきゃいけないことを>>428は理解してないのか?
shared_ptrの方で変えたら、通常利用で保護出来ないじゃないか。
435デフォルトの名無しさん:2005/03/30(水) 13:57:46
436ヽ(´ー`)ノ ◆.ogCuANUcE :2005/03/30(水) 18:14:32
437428:2005/03/31(木) 11:07:00
>>436
それです。
shared_ptr の人も交えて、実装に立ち入った問題点などが議論されていて、
日頃使っているだけの私では、良く分かりませんでした。
438ヽ(´ー`)ノ ◆.ogCuANUcE :int 2ch =05/04/01(金) 20:35:21
>>437
つか、Thread Index で変なとこに飛ばされて、
議論が追っかけずらいんだよね(´・ω・`)
439デフォルトの名無しさん:int 2ch =05/04/01(金) 23:10:42
440デフォルトの名無しさん:2005/04/10(日) 19:16:42
Spiritのアクションってなんで2引数必要なの?
値を代入したい時は冗長になるぅ...

expr = (str_p(L"1"))[boost::lambda::_1,boost::lambda::_2,data=1];
441デフォルトの名無しさん:2005/04/12(火) 10:09:35
template<class T> class A
{
public:
A(const A&); // 引数
A func() // 返り値
{
A a; // 自動変数
return a;
}
};

クラステンプレートで上記のコメントのところのように
Aとだけ書いた場合A<T>と同じ意味になる、という解釈は正しいですか?
442デフォルトの名無しさん:2005/04/12(火) 10:39:06
443441:2005/04/12(火) 11:09:04
>>442
ありがとう。よくわかりました。
444デフォルトの名無しさん:2005/04/22(金) 04:23:40
鬼車みたいに
マルチバイトで正規表現使えると速度面では有利なのかな?

ワイド文字で
System.Text.RegularExpressions(C#)
boost::wregex
boost::expressive
boost::spirit
試してみたけど敵わなかった...

鬼車>>C#>=boost::wregex>>expressive>>>>>>spirit
445444:2005/04/22(金) 04:52:13
>>444
spiritのパーサの型がわからんかったんで
毎回生成してたは...道理で遅いはずや...
typeid(parser).name()で出力された型にparser保存してループ回したら
鬼車=spiritになったわ...
逝ってくる...
446デフォルトの名無しさん:2005/04/22(金) 21:22:11
CommonLispの正規表現が最速
447デフォルトの名無しさん:2005/04/22(金) 23:32:46
>>445
当たり前だ。C++が遅かったら、コンパイラ言語を使って正規表現を扱う意味が
ないやんけ。
448デフォルトの名無しさん:2005/04/23(土) 01:11:14
コンパイラ言語?
式テンプレートを使ったメタプログラミングのこと?
449デフォルトの名無しさん:2005/04/23(土) 09:45:54
インタプリタ言語と比較してるだけっしょ
450デフォルトの名無しさん:2005/04/23(土) 10:03:21
またなんかミクロな揚げ足取りしてるんだろうね、きっとw
451デフォルトの名無しさん:2005/04/23(土) 10:19:30
>>448
友達いないでしょ。
452デフォルトの名無しさん:2005/04/23(土) 10:23:08
>>448
どういう風に表現すれば一番適切なのか教えて。

>>450-451
おまえらはどうでも良い。
453デフォルトの名無しさん:2005/04/23(土) 10:31:09
言い負けるのが余程悔しいんだろうな。
リアルな世界では気の強さが災いして、友達どころか彼女もいないと思われる。
家族にも総スカン。
454デフォルトの名無しさん:2005/04/23(土) 10:32:56
>>453
どうしてそういう返事をつけるのかな?
普段よっぽど抑圧されてるのか? もっと自分を愛そうね。
455デフォルトの名無しさん:2005/04/23(土) 10:36:57
スレタイ嫁
456デフォルトの名無しさん:2005/04/23(土) 10:51:39
>>447は、C++のコードをコンパイルして実行から速いと言っているのか、
汎用のDFSマシンじゃなくて、式テンプレートを使ったメタプログラミングで、
専用レクサーを生成して実行しているから速いと言っているのか、
どっちなんだ? 両方か?
457デフォルトの名無しさん:2005/04/23(土) 17:26:58
>>456
真性のアフォ?
458デフォルトの名無しさん:2005/04/24(日) 04:51:27
GCC 4.0.0 に TR1 が来ましたね。うれしい。
ソースは boost のごちゃごちゃしたコンパイラ分岐が無くなった分、
だいぶすっきりした印象
459445:2005/04/24(日) 10:46:47
spiritの型導出のためにファイル登録型のtypeof作ってみた。
#pragma once

#include<fstream>
#include<string>
#include<typeinfo>

template <typename T> struct id_of{enum {val=1};};
template <int N> struct id_to_type{};
template <> struct id_to_type<1>{};
#include"type_id_dynamic_impl.h"//(初回は空ファイルを用意)

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)
#define typeof(x) id_to_type<obj_class_id(x)>::type
460445:2005/04/24(日) 10:47:24
template<typename T> static void make_typeof(const T&,int ID)
{
std::string class_name = (std::string)(typeid(T).name());
for(int i=0;i<class_name.length();i++){
if(class_name[i]==':')class_name[i]=';';
else if(class_name[i]=='<')class_name[i]='(';
else if(class_name[i]=='>')class_name[i]=')';
}
std::string include_filename = "type_id_dynamic_impl_"+class_name+".h";
std::string include_file = "#include\""+include_filename+"\"";
std::fstream fo_d( "type_id_dynamic_impl.h" );
std::string buf;bool check=false;std::istream si(fo_d.rdbuf());
while(std::getline(si,buf))
if( buf==include_file )
check = true;
if(!check)
fo_d << include_file << std::endl;
fo_d.close();
std::ofstream fo( include_filename.c_str() );
fo <<"#pragma once" << std::endl;
fo << "template <> struct id_of< " << typeid(T).name() << " > { enum{ val = " << ID << " }; };" << std::endl;
fo << "template <> struct id_to_type< " << ID << " >{ typedef " << typeid(T).name() << " type; };" << std::endl;
fo.close();
}
461445:2005/04/24(日) 10:49:54
int main()
{
int a=100;
make_typeof(a,1212);//初回に必要
typeof(a) aa=100;//make_typeof実行後に有効
}
462デフォルトの名無しさん:2005/04/25(月) 22:32:41
これってtypeofを使う前にmake_typeofを書いた実行ファイルを走らせないといけないですよね?
実用上かなり使いにくくないですか?
463445:2005/04/26(火) 00:50:17
>>462
それは承知の上、自動で登録できる代償だと思ってる。
でも、type_id_dynamic_impl.hを書き換えるだけにすべきだろうな...
(ファイル大量発生とMAX_PATH超えちゃう問題あるだろうし)
登録してない場合はこんな感じでコード切り替えりゃ済む問題だし、
常用できないという点には同意。
#if if_exist_typeof(a)
typeof(a) aa=100;
#else
make_typeof(a,1212);
#endif
464デフォルトの名無しさん:2005/04/26(火) 00:53:50
BOOST_TYPEOF_REGISTER_TEMPLATEは飾りなんです
偉い人にはそれがわからんのです
465Lispのマクロテンプレート:2005/04/26(火) 01:04:31
俺の話を聴け〜♪
五分だけでいい〜♪
466デフォルトの名無しさん:2005/05/07(土) 00:44:34
俺しかいない羊羹マン
467デフォルトの名無しさん:2005/05/07(土) 00:47:41
ノシ
468デフォルトの名無しさん:2005/05/08(日) 12:54:43
質問です。
以下の要件を満たす型に対するtemplate class の
特別バージョンを作ろうと考えています。
・任意のContainer
・Container::value_typeがstd::pair
・Container::value_type::first_typeがint
・Container::value_type::second_typeは任意

例えば以下のようなものです。
std::vector<std::pair<int, int> >
std::deque<std::pair<int, char*> >
std::map<int, std::string>

これを実現するのに、どういった記述を行えばよいのでしょうか?

template<typename T> // これが一般の型を対象としたtemplate class である場合
class A {
//...
};

template<typename T, typename U> // ここらの書式は?
class A { // ここは?
// ?????....
};

よろしくお願いします。
469デフォルトの名無しさん:2005/05/08(日) 13:28:55
>>468
↓で map_with_string 以外は成功するみたい。(@ g++ 3.4.1)
そう簡単じゃないな。

#include <utility>

template< typename T >
struct A
{ static bool const is_specialized = false; };

template< template< typename > class ContainerTemplate , typename PairSecond >
struct A< ContainerTemplate< std::pair< int , PairSecond > > >
{ static bool const is_specialized = true; };

#include <vector>
#include <deque>
#include <map>
#include <string>

#include "boost/static_assert.hpp"

typedef std::vector<std::pair<int, int> > vector_with_int;
typedef std::deque<std::pair<int, char*> > deque_with_pchar;
typedef std::map<int, std::string> map_with_string;

BOOST_STATIC_ASSERT( A< vector_with_int >::is_specialized );
BOOST_STATIC_ASSERT( A< deque_with_pchar >::is_specialized );
BOOST_STATIC_ASSERT( A< map_with_string >::is_specialized );
470468:2005/05/08(日) 14:04:40
ありがとうございます。なんか凄い構文ですね…
vector,dequeとmapの特別バージョンを一緒に出来ない件に関しては、
以下のような感じでごまかすことにします。

template <typename T>
struct Base {
// implementation
static bool const is_specialized = true;
};

template < template <typename> class ContainerTemplate,
typename PairSecond>
struct A<ContainerTemplate<std::pair<int, PairSecond> > >
: public Base<A<ContainerTemplate<std::pair<int, PairSecond> > > > {
};

template < template <typename, typename> class ContainerTemplate,
typename PairSecond>
struct A<ContainerTemplate<int, PairSecond> >
: public Base <A<ContainerTemplate<int, PairSecond> > > {
};
471468:2005/05/08(日) 14:56:37
すみません、訂正です。
: public Base<ContainerTemplate<std::pair<int, PairSecond> > >
: public Base<ContainerTemplate<int, PairSecond> >
でした。
472デフォルトの名無しさん:2005/05/08(日) 22:00:30
std::vector<int, MyAlloc>なんかが、特殊化される悪寒w
473デフォルトの名無しさん:2005/05/09(月) 11:32:52
std名前空間のものを
std名前空間のもので特殊化ないし部分特殊化するのは
可能だがやっちゃダメ
474デフォルトの名無しさん:2005/05/09(月) 12:36:59
>>472
MyAlloc どころか普通の std::vector<int> も特殊化される罠

>>473
この場合、特殊化してるのは vector/deque/map じゃなくて
A のほうだから問題ないんじゃないかと思うんだが
475468:2005/05/09(月) 13:06:57
Baseで typedef typename T::value_type::first_type first_type
とか、諸々のstatic_assert置いておけばなんとかなると踏んでたんですが、
やっぱ変でしたかねぇ。
476468:2005/05/09(月) 13:22:32
たびたびすみません、これだとA<std::vector<int> >が作れないや。
勉強して出直します。
477473:2005/05/09(月) 16:30:48
>>474
あ、>>468のvector,deque等の例に対して言ったんです。
478468:2005/05/09(月) 17:44:25
>>473
468では、Aに渡す型の例としてvector,dequeをあげたのであって、
vector,dequeの特別バージョンを作ることを意図したわけではないのです。
479デフォルトの名無しさん:2005/05/09(月) 18:19:20
>468
ユーザ定義型が絡む場合ならば,std::vector等のstd名前空間内のテンプレートを
特殊化することは許されているんですけれどね.

そもそも468は恐らくソート済みシーケンスとstd::mapを汎用に扱おうとする意図だと
思いますけれど,これらは各種メンバ関数の宣言その他もろもろからして違うので
汎用に扱おうとするのはかなり無理がないですか?
480468:2005/05/09(月) 18:44:11
何度もすみません。
>そもそも468は恐らくソート済みシーケンスとstd::mapを汎用に扱おうとする意図だと
>思いますけれど,
その通りです。
>これらは各種メンバ関数の宣言その他もろもろからして違うので
>汎用に扱おうとするのはかなり無理がないですか?
無理がありました(汗 いろんなことが出来ませんでした。
とりあえず設計が悪かったということみたいです。
481デフォルトの名無しさん:2005/05/09(月) 18:52:39
>480
それがやりたいならstd::vectorやstd::dequeをラップして
std::mapの要求に合うようにするアダプタ作るのが恐らく最良じゃないかと思います.
それを状況に応じてstd::mapととっかえひっかえする感じで.
482デフォルトの名無しさん:2005/05/10(火) 00:38:29
boostにそんな感じのクラスなかったっけ?
似たようなニーズがあってboostを眺めたらあったので後で余裕があったら使おうと
思いつつ、遅いけどその場はstd::listで済ませたという覚えがある。
そういやその後試してなくてそのままになってるな。
483デフォルトの名無しさん:2005/05/10(火) 00:43:11
multi_index_container
484デフォルトの名無しさん:2005/05/10(火) 00:59:28
>>482
キーと値のアクセスの汎用化、ということなら property_map なんかもそうかな。
あとは boost-sandbox に associative_vector,vector_set なんてのもあるみたいだね。
485デフォルトの名無しさん:2005/05/10(火) 01:05:27
>>480
まあ実用性のことは置いておいて、メタプログラミングのいい勉強になるかな、
と思ってちょっと書いてみた。
ここは BOOST スレじゃないので、敢えて boost::mpl とかは使わず。

template <class T0, class T1>
struct is_same_type {
 static const bool value = false;
};
template <class T>
struct is_same_type<T, T> {
 static const bool value = true;
};

struct sfinae_type {
 typedef char one;
 typedef struct { char arr[2]; } two;
};

template <class T>
struct has_key_type : sfinae_type {
 template <class U> static one test(typename U::key_type*);
 template <class U> static two test(...);
 static const bool value = (sizeof(test<T>(0)) == 1);
};
template <class T>
struct has_value_first_type : sfinae_type {
 template <class U> static one test(typename U::value_type::first_type*);
 template <class U> static two test(...);
 static const bool value = (sizeof(test<T>(0)) == 1);
};
486デフォルトの名無しさん:2005/05/10(火) 01:06:01
template <class T, bool HasKeyType, bool HasValueFirstType>
struct A_specialized_impl {
 static const bool value = false;
};
template <class T, bool HasValueFirstType>
struct A_specialized_impl<T, true, HasValueFirstType> {
 static const bool value =
  is_same_type<int, typename T::key_type>::value;
};
template <class T>
struct A_specialized_impl<T, false, true> {
 static const bool value =
  is_same_type<int, typename T::value_type::first_type>::value;
};

template <class T>
struct A_specialized
 : A_specialized_impl<
   T,
   has_key_type<T>::value,
   has_value_first_type<T>::value
  > {};

template <class T, bool Specialized = A_specialized<T>::value>
struct A { ... }; // 通常版

template <class T>
struct A<T, true> { ... }; // 特殊化版
487デフォルトの名無しさん:2005/05/10(火) 02:23:21
>485
細かいことですけどmapのkey_typeってconstですよ.

SFINAEのこういう使い方はあくまで
「必要条件を満たさないものを振り落とす」ってだけなんですよね.
それにできることが基本的な型特性と内部型の存在のテストくらいだし・・・.
せめてメンバ関数の存在をテストできればもう少し面白いと思うんですけれど.
488デフォルトの名無しさん:2005/05/10(火) 03:24:21
>>487
いや、value_type が pair<const Key, T> なのであって、
key_type は Key のままだよ。
そうでないと一時変数作れないし。
489デフォルトの名無しさん:2005/05/10(火) 09:27:04
>>487
> せめてメンバ関数の存在をテストできればもう少し面白いと思うんですけれど.

typeof(メンバ関数)で何とかなります。
490デフォルトの名無しさん:2005/05/10(火) 10:28:50
>488
マジボケしてました・・・.

>489
何とかなります?typeofってそもそも非標準ですし.
491ヽ(´ー`)ノ ◆.ogCuANUcE :2005/05/10(火) 10:36:09
>>490
まだ sandbox だけど boost::typeof とか。
boost スレかどっかで見たけど、どこだったか忘れた。
492デフォルトの名無しさん:2005/05/10(火) 14:30:49
>>489
これとか見ると、メンバ関数のシグネチャが分かれば
なんとかできそうな気はする
ttp://lists.boost.org/MailArchives/boost/msg70844.php
493デフォルトの名無しさん:2005/05/10(火) 22:34:40
>>491
typeofがあってもメンバがなければ単にコンパイルが失敗するだけじゃないですか?

>>492
汎用プログラミングの文脈だと「〜〜というシグネチャを持ったメンバ関数があるかどうか」というテストより
「〜〜という構文でメンバ関数が呼び出せるかどうか」というテストの方が重要だと思うので,
そこで使われている技法は少なくとも汎用プログラミングでは非常に使いづらいような気がします.
それにその技法,言語規格的に結構スレスレなことやってるので,GCCではうまく通らなかったり
VC7.1でもうまく機能しないケースがあったり・・・.
494デフォルトの名無しさん:2005/05/11(水) 00:30:14
>>493
> typeofがあってもメンバがなければ単にコンパイルが失敗するだけじゃないですか?

traitsみたいなんじゃ不十分で、条件分岐とかしたいという事?
495ヽ(´ー`)ノ ◆.ogCuANUcE :2005/05/11(水) 10:34:33
>>493
失敗するだけだね。boost::mpl::has_xxx とかで何とかできないかとも思ったが、
寝不足なせいか、頭がこんがらがってきた。
496デフォルトの名無しさん:2005/05/11(水) 19:59:54
>>494
そうです.traitsというよりはintrospectionといったほうが適切ですかね.
traitsはユーザが明示的に特殊化する分,確実ですけれど一方で面倒な側面もあると思うので,
ある程度は要件を自動的にテストしてくれたほうが楽かなという発想です.

>>495
boost::mpl::has_xxxは内部型の存在テストにしか使えないです.
497デフォルトの名無しさん:2005/05/12(木) 00:23:09
>>496
> そうです.traitsというよりはintrospectionといったほうが適切ですかね.

traitsとも違い、
virtual classをinheritしたり、
interfaceをimplementsするのとは違う用途は、
具体的にどういうものを想定しているんですか?
498デフォルトの名無しさん:2005/05/12(木) 03:28:39
>>497
>具体的にどういうものを想定しているんですか?
いや,あまりろくなことを考えていないんですが,一応,型がどのコンセプトの
モデルなのかを識別するための手段として使えないか,と想定していました.
型がどのコンセプトのモデルであるかを識別できれば,クラステンプレートの特殊化や
汎用関数のオーバーロード選択をより柔軟にできるんじゃないかという考えです.例えば

template<class Iterator, class T>
void replace(Iterator first, Iterator last, T const &x);

という汎用関数があって,TがIteratorの値型に変換可能な型ならstd::replaceの機能で,
TがIteratorの値型を受ける単項述語ならstd::replace_ifの機能といった具合です.
逆に言うと,STLはこのようなコンセプトに基づいたオーバーロード選択の技術がないので
replaceとreplace_ifとに名前を分けざるを得なかった,とも言えると思います.
で,仮に例えばTのoperator()がIteratorの値型で呼び出せるかどうかを
テストできるような実装技術があれば,traitsの明示的な特殊化に頼ることなく
上記のような高度な振り分けができるんじゃないか,という考えです.
ただ,もちろんメンバ関数の存在テストはコンセプトの必要条件を調べられるだけで,
決してコンセプトのモデルであるための十分条件を調べることにはならないのですが・・・.
499デフォルトの名無しさん:2005/05/12(木) 03:29:37
・・・ということを想定していたんですが,

http://tinyurl.com/as9k5

上のような議論を見つけたので読んでみた結果,やはりtraitsの特殊化などで
明示的に表明する方が良いような気がしてきました.より根本的には
言語としてこういうことを直接サポートしてくれればもっとうれしいのですけれど.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1758.pdf
500デフォルトの名無しさん:2005/05/12(木) 12:05:02
上記PDFもそうだけど、D&Eの書き下ろし前文(-1章)を見ても、
コンセプト回りの拡張が c++0x でなされる可能性は高いんじゃないかな。

ただ、Stroustrup としても
テンプレート回りのエラーメッセージの酷さを何とかすることや、
テンプレート宣言と定義の分離問題を何とかするために導入したいような
感じだし、基本的にはコンパイル時検査の強化を目的としたものであって、
オーバーロード選択などに使われるようなものではないと思う。

例えば、関数ポインタのシーケンスがあったとして、
operator== による find なのか、operator() による find_if なのか、
コンセプトだけでは判断できないケースもあるわけで。
501デフォルトの名無しさん:2005/05/12(木) 19:39:36
>>500
> 使われるようなものではないと思う。

けど,使われるようなものではないものに,使われて驚くのがtemplateだしなあ…
502デフォルトの名無しさん:2005/05/13(金) 01:07:52
>>500
>テンプレート回りのエラーメッセージの酷さを何とかすることや、
>テンプレート宣言と定義の分離問題を何とかするために導入したいような
これは前々からずっと言ってますからねぇ.近い将来標準に導入されると信じていますけれど.

>例えば、関数ポインタのシーケンスがあったとして、
>operator== による find なのか、operator() による find_if なのか、
>コンセプトだけでは判断できないケースもあるわけで。
う,やはりここ突っ込まれますよね・・・.こういう曖昧なケースではユーザが
明示的に曖昧性を解消するような方向を想定してました.微妙ですけれど.

やはり現在の段階では,コンセプトに基づくオーバーロード選択や
テンプレートの特殊化といった発想は飛躍しすぎている感がありますね.
503デフォルトの名無しさん:2005/05/14(土) 03:29:59
参照templateのパラメータに制限あるのかな?
グローバル変数しか使えないみたいなんだが...

struct A{};
template <A& a>struct C{};

A a;//OK

int main()
{
A a;//NG
C<a> c;
}
504デフォルトの名無しさん:2005/05/14(土) 05:10:48
>503
14.3.2 Template non-type arguments
4 [Note: Temporaries, unnamed lvalues, and named lvalues that do not have external linkage
are not acceptable template-arguments when the corresponding template-parameter has reference type.
14.3.2-1 の補足。
505デフォルトの名無しさん:2005/05/14(土) 09:10:05
テンプレートはコンパイル時に生成されるわけで
mainの方のaは実行してみないとどこに作られるかわからないわけで
そのaをテンプレート引数にstruct Cは生成できないわな。
506デフォルトの名無しさん:2005/05/15(日) 21:00:03
VisualC++7.1なんですが、テンプレートコンストラクタの明示的なインスタンス化をしたいんですが
コンパイルが通りません。なぜでしょうか?

class A
{
public:
template< typename B > A( B b){;}
};

template< > A::A< int >( int b); // error C2143: 構文エラー : ';' が '<' の前にありません。 他
template A::A< int >( int b); // error C2143: 構文エラー : ';' が '<' の前にありません。
507デフォルトの名無しさん:2005/05/15(日) 21:28:04
>>506
ttp://www.kuzbass.ru/docs/isocpp/template.html#temp.expl.spec
ここに明示的な特殊化の対象となるものがリストされているんだが、
"member function template of a class template" はあるけど、
"member function template of a class" は無いな。

できないのかもしれない。
508デフォルトの名無しさん:2005/05/15(日) 21:51:51
>>506>>507
多分これ。
14.5.2.5
[Note: because the explicit template argument list follows the function template name,
and because conversion member function templates and constructor member function templates
are called without using a function name, there is no way to provide an explicit template argument list
for these function templates. ]
コンストラクタは関数名を持たないので、メンバテンプレートにされたコンストラクタおよび
変換メンバ関数テンプレートは明示的に実引数を与えられないって事っすね。
C++の不具合とも言えるので、次期C++規格ではfixして欲しいですな。
509デフォルトの名無しさん:2005/05/15(日) 21:56:00
>>506
理解しました。ありがとうございました。
しかし皆さん凄いですね。
510デフォルトの名無しさん:2005/05/15(日) 21:56:33
>>506
というわけで
「コンストラクタテンプレートぐらいhppに全部書いちゃえば良いじゃない」
もしくは
「コンストラクタテンプレート内の処理を静的メンバ関数に委譲して
(この部分だけはhppに書く必要アリ)
委譲先の静的メンバ関数を明示的にインスタンス化すれば良いじゃない」
511デフォルトの名無しさん:2005/05/15(日) 22:32:53
ん?これでできてるっぽいぞ。
template<> A::A( int b);
512デフォルトの名無しさん:2005/05/15(日) 23:29:21
>>511
あれ?本当だね。という事は、template <>の構文がちゃんとメンバテンプレート
に適用されているみたいだね。俺の勘では、明示的特殊化になってなくて、単なる
オーバーロードのような気もするが・・・・
513デフォルトの名無しさん:2005/05/15(日) 23:36:57
もう少し規格票をよく読んでみる・・・・・
>>508はそしたら違う事に関してなのかな。
514デフォルトの名無しさん:2005/05/15(日) 23:41:09
>>511
しかし、そのコードは構文的に正しいとは言えないですよね。
謎だ。
515デフォルトの名無しさん:2005/05/15(日) 23:41:17
特殊化とインスタンス化とを混同してない?
516デフォルトの名無しさん:2005/05/15(日) 23:55:33
>508が示したように、コンストラクタテンプレートに対して
テンプレート引数を明示する方法は無い。
しかし、(メンバ)関数テンプレートの特殊化を宣言する再には、
テンプレート引数を明示しなくても、関数引数の型から
テンプレート引数の推測が働く。

>>514
明示的特殊化の構文は
 template<> delcaration
だから、>511は構文的に正しいと言える。
517デフォルトの名無しさん:2005/05/15(日) 23:58:48
構文的には確かに正しいのだけれど、もともとの506の要求は
明示的インスタンス化(≠明示的特殊化)なわけで・・・
518デフォルトの名無しさん:2005/05/16(月) 00:02:05
勉強になった。
519デフォルトの名無しさん:2005/05/16(月) 00:08:01
>>517
それがどうした?
明示的インスタンス化の構文は
 template declaration
だ。あとは同じ。
520デフォルトの名無しさん:2005/05/16(月) 00:12:53
>>519
すまんすまん。それでVC++7.1で通ったよ。
521デフォルトの名無しさん:2005/05/16(月) 00:15:29
コンパイラに「これこれのテンプレートをT型でインスタンス化しますた」
とレポートするスイッチがあればいいのに
522デフォルトの名無しさん:2005/05/16(月) 00:17:31
実体化の位置を決定するルールは結構複雑だからな。
523デフォルトの名無しさん:2005/05/16(月) 00:59:29
おまえらの必死さに笑った。
C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、
まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
524デフォルトの名無しさん:2005/05/16(月) 01:03:16
C++知らないのに、知ってる振りして
がんばって煽るアンタもそうとう必死だが
525デフォルトの名無しさん:2005/05/16(月) 01:35:46
むしろC++で駄目なのは
テンプレートじゃなくてコンストラクタ
526デフォルトの名無しさん:2005/05/16(月) 01:47:19
>>525
コンストラクタの何が不満だって?
527デフォルトの名無しさん:2005/05/16(月) 02:48:50
純粋なOO言語と比べると
C++のOOは不完全
528デフォルトの名無しさん:2005/05/16(月) 03:05:21
>>526

class A
{
int a;
public:
A( int a_ ) : a(a_){;}
};

class B : A
{
public:
B(){ int a = 略; A::A(a);}
B( int a ) : B(){;}
};
529デフォルトの名無しさん:2005/05/16(月) 03:16:11
何がしたいのか理解に苦しむ。C++について理解しているとは思えないコードだ。
530デフォルトの名無しさん:2005/05/16(月) 03:30:52
>>529
これが出来ないから嫌だなと。

>B(){ int a = 略; A::A(a);}
これはAに突っ込む引数aを
Bのコンストラクタ内で生成したい時。
C++ではAのコンストラクタは、Bの初期化リストにしか
置けないので複雑なロジックは難しい。

>B( int a ) : B(){;}
これは多重定義したコンストラクタから
デフォのコンストラクタを予呼びたい時。
デフォのコンストラクタに生成時にかならず呼ばれる
初期化コードを収める。
これが出来ないと全てのコンストラクタに
同じ初期化コードを書かなければならない。
531デフォルトの名無しさん:2005/05/16(月) 04:43:03
>>530
最初の:AはBの基底クラス。最初にAが構築されなきゃBが構築できない。

2番目の:B() {Init();} B(int a) {Init();hogehoge(a);}
532デフォルトの名無しさん:2005/05/16(月) 08:55:21
最初のは
static int hoge() {return 略}
B() : A(hoge()) {}
とかすれば。
533デフォルトの名無しさん:2005/05/16(月) 09:05:50
>>530
そういうことか。
ではどうしたらいいと思う?
Dは両方いけるんだっけか?
534デフォルトの名無しさん:2005/05/16(月) 09:06:24
>>531
> Aが構築されなきゃBが構築できない
関係ない。

> Init()
Init() の中に初期化リストが書けない。
535デフォルトの名無しさん:2005/05/16(月) 09:07:23
>>532
hoge() の値を初期化リストで2度使いたくなったらやっぱり困るな。
「略」が軽くて副作用がなければ、2回呼び出すんだろうけど。
536デフォルトの名無しさん:2005/05/16(月) 09:10:37
要は設計が悪いんだろ。
537デフォルトの名無しさん:2005/05/16(月) 09:18:31
まあそうだな。C++の設計の悪さは今更いかんともしがたい部分がある。

538デフォルトの名無しさん:2005/05/16(月) 11:19:33
>>530
> C++ではAのコンストラクタは、Bの初期化リストにしか
> 置けないので複雑なロジックは難しい。

コンストラクタの途中でexceptionが起きたことを考えると、
>>532のような方法で初期化リストを旨く使う方法に頭を悩ませるのが良い。
>>528のやり方ではコンストラクト失敗時のデストラクトの扱いがかなり難しくなる。

初期化リストで上手くできない場合は、
exception safeの事を考えるとコンストラクタ自体がかなり複雑になってしまう。
539>>538:2005/05/16(月) 11:21:07
定義順じゃなくて、初期化リスト記述順だといいのになあと思ったことはある。
540デフォルトの名無しさん:2005/05/16(月) 12:06:24
>>539
それだと、コンストラクタごとに初期化順が変わってしまう。
Ex.
class foo {
public:
foo() : a_(), b_() {}
foo(int a) : b_(a), a_(a) {}
...;
};
541デフォルトの名無しさん:2005/05/16(月) 12:21:40
>>540
539はまさにそれを意図しているのだと思うが、何か不都合があるの?
542デフォルトの名無しさん:2005/05/16(月) 12:53:52
>>541
初期化リストに載ってないメンバはどうすればいい? by コンパイラ
543デフォルトの名無しさん:2005/05/16(月) 13:14:10
くるしゅうない。よきにはからえ。
544デフォルトの名無しさん:2005/05/16(月) 13:17:59
構築した順番の逆順で解体することを保証しなきゃならんので
コンストラクタごとに初期化順が変わったら大変だ。
545デフォルトの名無しさん:2005/05/16(月) 14:05:33
なるほど。それもそうだ。

546デフォルトの名無しさん:2005/05/16(月) 15:32:47
つーか藻前らEffectiveC++くらい読んどけよ。
547デフォルトの名無しさん:2005/05/16(月) 20:25:46
template< uint n > class X
{
public:
void f(...);
}

こういうクラスがあったとして、

nが1だった場合 → X::f( uint f0 );
nが2だった場合 → X::f( uint f0, uint f1 );
nが3だった場合 → X::f( uint f0, uint f1, uint f2 );

こういうふうにテンプレート引数によって
関数の引数の数が変わるようにしたいんですが可能ですか?
出来ないまでも、代替手段みたいなのはありますか?
548デフォルトの名無しさん:2005/05/16(月) 20:53:37
あの〜
templateって実はマクロ?
549デフォルトの名無しさん:2005/05/16(月) 21:23:34
>>547
関数のデフォルト引数でなんとかしろ。同一のテンプレートパラメータの型を
持つクラスは2回以上は定義できん。
550デフォルトの名無しさん:2005/05/16(月) 21:58:37
>>549
了解、こういうのも出来るといいですね。
551デフォルトの名無しさん:2005/05/16(月) 22:15:27
いやだから、ディフォルト引き数で何が不満なんだ?
552デフォルトの名無しさん:2005/05/16(月) 22:22:47
それぞれ特殊化で可能じゃない?もちろんそうするのが良いか悪いかは別。
553デフォルトの名無しさん:2005/05/16(月) 22:26:17
>>551
例えばベクトルクラスがあります。
template< uint n >class vector;

これをインスタンス化したい場合、こういうふうに書きたいんです。
vector<2> v2 = vector<2>(5,1);
vector<3> v3 = vector<3>(5,1,6);
vector<4> v4 = vector<4>(5,1,6,3);
vector<5> v5 = vector<5>(5,1,6,3,9);
vector<100> v100 = vector<100>(5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9);

自然な欲求だと思います。
554デフォルトの名無しさん:2005/05/16(月) 22:31:08
>>553
そういう時のためのstd::vectorではないかと思うのだが・・・・
555デフォルトの名無しさん:2005/05/16(月) 22:34:16
static const uint initialValues[] = {5, 1, 6, 3, 9,};
std::vector<uint> v5 = std::vector<uint>(initailValues, initialValues + sizeof(initialValues) / sizeof(*initialValues));
556デフォルトの名無しさん:2005/05/16(月) 22:34:58
その例なら
配列を初期化して、std::vectorにぶち込めばいいじゃん
どうしてもやりたいならBOOST_PPで特殊化
557デフォルトの名無しさん:2005/05/16(月) 23:09:19
部分特殊化。以降略。なんか馬鹿みてえ。
#include <iostream>
#include <cstddef>

template <std::size_t N, typename T = int>
class vec {
T a[N];
public:
vec(T i) {
a[0] = i;
std::cout << a[0] << std::endl;
}
};

template <typename T>
class vec<2, T>
{
T a[2];
public:
vec(T i, T j) {
a[0] = i; a[1] = j;
std::cout << a[0] << ' ' << a[1] << std::endl;
}
};

int main()
{
vec<1> v1 = vec<1>(5);
vec<2> v2 = vec<2>(5,1);
}
558デフォルトの名無しさん:2005/05/16(月) 23:21:18
特殊化はイヤというか面倒くさすぎるから、普通はこんなカンジだろうね

template<uint Dim> class vector {
double *const coord;
public:
vector(double x) : coord(new double[sizeof(char[Dim == 1]) * Dim])
 { coord[0] = x; }
vector(double x, double y) : coord(new double[sizeof(char[Dim == 2]) * Dim])
 { coord[0] = x; coord[1] = y; }
vector(double x, double y, double z) : coord(new double[sizeof(char[Dim == 3]) * Dim])
 { coord[0] = x; coord[1] = y; coord[2] = z; }
};

int main() {
vector<1> v(1);
vector<1> v1(1, 2); // error
vector<2> v2(1, 2);
vector<2> vv2(1); // error
vector<3> v3(1, 2, 3);
}
559デフォルトの名無しさん:2005/05/16(月) 23:24:56
やはりコンストラクタのオーバーロードに落ち着くか。
560デフォルトの名無しさん:2005/05/16(月) 23:25:18
>>
そうするまでもなく
普通に多重定義でいいと思うよ。

template <std::size_t N, typename T = int>
class vec {
T a[N];
public:

vec( T x, T y)
{
if( N > 0 )a[0] = x;
if( N > 1 )a[1] = y;
}

vec( T x, T y, T z)
{
if( N > 0 )a[0] = x;
if( N > 1 )a[1] = y;
if( N > 2 )a[2] = z;
}

};
561デフォルトの名無しさん:2005/05/16(月) 23:27:04
ちなみに、 sizeof(char[Dim == 1]) ってのは、
Dim == 1 のときは、1 で、そうでなければ、コンパイルエラーね
562デフォルトの名無しさん:2005/05/16(月) 23:59:25
どうも読みにくいので、直した

template<unsigned Dim> class vector {
 double coord[Dim];
public:
 vector(double x) {
  sizeof(char[Dim == 1]); // Dim == 1 でなければエラー
  coord[0] = x;
 }
 vector(double x, double y) {
  sizeof(char[Dim == 2]); // Dim == 3 でなければエラー
  coord[0] = x; coord[1] = y;
 }
 vector(double x, double y, double z) {
  sizeof(char[Dim == 3]); // Dim == 3 でなければエラー
  coord[0] = x; coord[1] = y; coord[2] = z;
 }
};

int main() {
 vector<1> v(1);
 vector<1> v1(1, 2); // コンパイルエラー
 vector<2> v2(1, 2);
 vector<2> vv2(1); // コンパイルエラー
 vector<3> v3(1, 2, 3);
}
563デフォルトの名無しさん:2005/05/17(火) 02:55:12
おまえらの必死さに笑った。
C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、
まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
564デフォルトの名無しさん:2005/05/17(火) 02:57:49
×メンテ不能
○俺に理解不能
565デフォルトの名無しさん:2005/05/17(火) 07:37:28
あーあ、4,5,6って別々にするわけ?テンプレの意味ねー
566デフォルトの名無しさん:2005/05/17(火) 07:41:46
テンプレートはマクロ
www.iba.k.u-tokyo.ac.jp/〜yanai/template_tips.html
567デフォルトの名無しさん:2005/05/17(火) 10:05:48
>>563
まあ同意。boostとか見てても思うが、言語使用の範囲内でどうにかしようとするから無理が出てくる。
パズルとしては興味深いが、無理やりやってるからどうしてもキモくなる。
新しいプリプロセッサ作ったほうがマシな気がする。
568デフォルトの名無しさん:2005/05/17(火) 12:24:00
>>566
典型的なアホっぽいが。

exportはComeauでサポートされていることすら知らんようだし。
569デフォルトの名無しさん:2005/05/17(火) 12:40:07
>>566
> まず最も重要な事実は、templateはマクロであるということである。
そもそも、始めの仮定についてキチンと論証してない時点でアウトだな。
570デフォルトの名無しさん:2005/05/17(火) 13:16:28
templateはマクロだよ。
マクロと聞いてCやC++のプリプロセッサ(やVBAなどアプリケーション内のスクリ
プティング言語)しか思いつかない人に向けた文章ではなかろ。

571デフォルトの名無しさん:2005/05/17(火) 14:01:12
>ここではオブジェクト指向に則ったよいtemplateの使い方を模索する。
この時点で道を誤っている気が。
572デフォルトの名無しさん:2005/05/17(火) 14:29:53
templateの明示的インスタンス化なんて、少し考えれば
使い道などろくに無い機能だとわかるだろうに
しかも使う必要も無い機能だし
それにこだわってる時点で、ダメだなそのページ
573デフォルトの名無しさん:2005/05/17(火) 18:56:42
ネタをまじめに叩くなよ
574デフォルトの名無しさん:2005/05/17(火) 20:39:55
ねたじゃねーし
templateはコンパイルする前に展開されるからマクロなの
575デフォルトの名無しさん:2005/05/17(火) 20:42:50
コンパイルする前に展開しちゃったら
タイプセーフは無理じゃないの?
576デフォルトの名無しさん:2005/05/17(火) 20:47:38
いいよわからん奴は無理に使うな
577デフォルトの名無しさん:2005/05/17(火) 21:03:14
マクロで使える構文を限定的にして型を認識させたのがテンプレート
578デフォルトの名無しさん:2005/05/17(火) 21:12:28
みんな好き勝手に「マクロ」の意味を定義して使ってるから、話が噛み合わない
だけでしょ。
579デフォルトの名無しさん:2005/05/17(火) 21:56:51
おっと、ここで578が正式にマクロの定義とやらを教えてくれるらしいぞ
580デフォルトの名無しさん:2005/05/17(火) 22:03:42
なにこの意味不明な反応
581デフォルトの名無しさん:2005/05/17(火) 22:21:02
付き合うだけ無駄でつ
582デフォルトの名無しさん:2005/05/18(水) 07:21:54
普通のマクロでも引数の数を変えられるようなことはできないから
>>553
583デフォルトの名無しさん:2005/05/20(金) 00:28:48
VC7.1で
std::list<int>使うとポインタの保存のためか
std::vector<int>の3倍近いメモリ使うんだが、
省メモリな実装のlistって無理なのかな?
584デフォルトの名無しさん:2005/05/20(金) 00:55:57
>>583
SGI STLのstd::slistなら、一方向リストだけど、少しでも少ないかも。
585デフォルトの名無しさん:2005/05/20(金) 01:45:41
リストすら作りを理解してないのかよ。
586デフォルトの名無しさん:2005/05/20(金) 12:25:58
std::vectorのresizeコストが気になるようならstd:;dequeとか
587デフォルトの名無しさん:2005/05/21(土) 00:07:18
つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが
588583:2005/05/21(土) 00:47:56
サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector)
を同時に満たしたかったので...
とりあえず挿入削除の速いlistを選択したけど、以外とメモリ食うって分かった。

小規模のvectorをlistで繋ぐか584さんのslistつかうのがいい気がしてきた。
双方向リストだとポインタが64bit化したらさらに事態は悪化するのも気になるし...
589デフォルトの名無しさん:2005/05/21(土) 00:53:20
だから小規模なvectorをつなぐぐらいならdeque使えってばよ
590デフォルトの名無しさん:2005/05/21(土) 00:54:03
>>587
要素が int で、双方向のポインタがあるわけで
それぞれサイズが同じなら、int の 3倍ですね。
>>585 も指摘してますが、糞当たり前です。
591デフォルトの名無しさん:2005/05/21(土) 00:54:46
>588
データ構造の勉強からやり直して来い。
592デフォルトの名無しさん:2005/05/21(土) 00:55:27
s/int の/1要素あたり int の/
593デフォルトの名無しさん:2005/05/21(土) 00:56:22
>>588
中身の小さいオブジェクトを入れると、相対的にlistはポインタなどの管理部分が
大きく見えてしまうからねえ。
ケースバイケースで使い分けるしかない。
それとstd::slistのiteratorは、forward iteratorなので、bidirectional iteratorのlist
に比べると実行効率の悪いメンバ関数がいくつか存在するから、その点もよく確かめてね。
594583:2005/05/21(土) 01:04:49
dequeだと
中間への挿入、削除した場合に
参照と反復子が死滅。

595デフォルトの名無しさん:2005/05/21(土) 01:05:46
>>588
テキストエディタみたいに、挿入が同一箇所に連続して発生するようなら
ギャップベクタを検討するといいかも
596デフォルトの名無しさん:2005/05/21(土) 01:34:23
>>594
それが問題になるなら、もう list しかないんじゃないかなぁ。
「小規模のvectorをlistで繋ぐ」なんてのも、全然ダメだろ。
597デフォルトの名無しさん:2005/05/21(土) 01:43:48
もはやtemplateの話題じゃなくて、「データ構造とアルゴリズム」の世界だな。
598デフォルトの名無しさん:2005/05/21(土) 02:11:25
listとかvectorはあるのに、より優れた概念のS式がないのはおかしい
599デフォルトの名無しさん:2005/05/21(土) 03:42:02
>>598
あなたね(汗
インタプリタじゃないんですから。
600デフォルトの名無しさん:2005/05/21(土) 05:55:52
>>599
もっと詳しく。

・・・って言っても無駄か。
何もわかってないくせに噛み付いてるの見え見えだもんな。
601デフォルトの名無しさん:2005/05/21(土) 08:25:20
S式ってツリー構造じゃ無かったっけ?違った?
602デフォルトの名無しさん:2005/05/21(土) 08:41:31
>>600
赤黒木だけじゃ足りないってのかい。
603デフォルトの名無しさん:2005/05/21(土) 09:18:31
>>597
STLネタがそっちに向かうのは自然だと思うけど?
604デフォルトの名無しさん:2005/05/21(土) 09:22:59
> つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが
直前の要素のポインタと直後の要素のポインタの排他的論理和演算結果を保持しておけ。
そうしておけばポインタ1つで双方向からリストをたどることができる。

実行時にそれなりのコストはかかるが、、、
605デフォルトの名無しさん:2005/05/21(土) 10:01:07
>>604
結局サイズは変わらないわけだが。
しかも「ポインタ同士のXOR」?ワケワカラン。
606604:2005/05/21(土) 10:23:45
以下のようなリンクリストがあったとする。

A‐B‐C

この時、B のポインタ領域には &A ^ &C となる値がセットされることになる。
順方向でA、Bまで読み込んできた場合、Aのアドレスは判っているはず。
このため、&A ^ (&A ^ &C) を計算することでCのアドレスが取得できる。

同様に逆方向でC、Bまで読み込んでいる場合、Cのアドレスは判っているため、&C ^ (&A ^ &C) を計算することでAのアドレスが取得できる。

これが magic list というデータ構造。
607デフォルトの名無しさん:2005/05/21(土) 10:35:12
>>606
代償としてイテレータのサイズが大きくなるから、使い道は微妙だけどな。
608デフォルトの名無しさん:2005/05/21(土) 10:43:01
>>606
ふーん。
std::list の実装に使われてるのは見たこと無いんだけど、
標準コンテナの実装としては何か問題があるのかな?

と考えたら、イテレータを取得した後に要素の削除・追加をするとマズイような気がした。
609デフォルトの名無しさん:2005/05/21(土) 10:44:00
>>604
リストを変更しないときのコストはたいしてかからないんじゃないか。
簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。

>>607
イテレータのサイズなんて問題になることがそうそうあるとは思えんが。

前後に追加削除があるとイテレータが無効になってしまうから
std::listとはコンパチにならなくなることの方がまだ問題になりそうだ。
610604:2005/05/21(土) 10:50:55
>>607
イテレータのサイズとリンクリストに保持される各要素のデータサイズを同列で比較するのもどうかと思うが。

イテレータにポインタを2つほど追加したところで、8バイトしかサイズは増えない。
(処理が複雑化する分、イテレータオブジェクトのサイズはもう少し増えると思うが。)
しかし、双方向ポインタにしてしまうと、各要素毎に4バイトの投資が必要となる。
611604:2005/05/21(土) 10:58:43
>>608>>609
確かにイテレータの取得後に前後の要素が追加削除されると痛い。
排他制御の問題を抱え込むから、std::list との互換性は考えない方が吉かと。
612デフォルトの名無しさん:2005/05/21(土) 11:12:46
>>609
> 簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。

訂正。これ間違い。xor+mov*2(or xchg)になるな。


613デフォルトの名無しさん:2005/05/22(日) 00:18:22
> サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector)
データの格納にset使うのってやっぱダメなのか?
setの中身はconst扱いだけど、外してswapして取り出して消して使ってるけど。
挿入時もヌルデータ入れて跡で要素をswapしてるんで無駄なコピーも出ない用に工夫して、、、
、、、、

vectorはサイズ増えると勝手に自分のコピー作るんで、reserveしなきゃならんので嫌だ。
lispは探索が遅いし。mapはそんなものに使うのもったいないし。

結論 : set使え!
614デフォルトの名無しさん:2005/05/22(日) 00:31:16
setが泣いてるぞ
615デフォルトの名無しさん:2005/05/22(日) 00:31:37
listのメモリ効率が気になるような状況でsetなんか使えるかよ
つーか、dequeって要素へのアクセスもそこそこ速くサイズ変更のコストも最小限なのになんで使われんのか。
616デフォルトの名無しさん:2005/05/22(日) 03:41:02
>>615
dequeって要素へのアクセスもそこそこ速く
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
環境によってはlist並みに遅いわけですが何か?
OSやCPUは敢えて書かないが、STLportとかSTLportとかSTLportとか。
617デフォルトの名無しさん:2005/05/22(日) 06:50:59
>>606
C++ でポインタにビット毎の論理演算なんて
吉外じみた真似、よく平気で出来ますね。
618604:2005/05/22(日) 08:36:41
>>617
坊やだな、、、
ポインタと言えど所詮はビット列なのだよ。
619デフォルトの名無しさん:2005/05/22(日) 08:39:59
>>618
reinterpret_castとか使わないといけないんだろ?
環境依存イクナイ(・A ・)!
620デフォルトの名無しさん:2005/05/22(日) 08:55:43
>>606
面白いなぁ
621604:2005/05/22(日) 08:55:52
>>619
reinterpret_castが即、環境依存につながるとは新鮮な考え方だな。
同じ環境内でキャストして、同じ環境内で元に戻すのであれば、環境依存も何もないだろうに(それを環境依存というのなら、コンパイラが吐くコードはすべて環境依存になるぞ)。
それとも、そういうことすら期待できない処理系が現存するというのか?
(そんなのが出てきた時点で reinterpret_cast は言語仕様から外されるだろうて。)
622デフォルトの名無しさん:2005/05/22(日) 09:07:29
>>621
愉快な香具師だなお前。
C++の実装と進化の§14.3.3(P420)読んでみろ。
623デフォルトの名無しさん:2005/05/22(日) 09:09:30
>>622
○C++の設計と進化
×C++の実装と進化

それから、規格票を優先しろ。
624604:2005/05/22(日) 09:17:26
その本は持ってない。
引用の範囲内だろうから、出典を明記して引用してくれ。
内容を咀嚼して説明してくれてもよいぞ。
625620:2005/05/22(日) 09:35:20
俺の面白いは純粋な意味であって、622と同じ意じゃないですよ
626デフォルトの名無しさん:2005/05/22(日) 09:38:55
5.2.10 Reinterpret cast

4 A pointer can be explicitly converted to any integral type large enough to hold it.
The mapping function is implementation-defined [Note: it is intended to be unsurprising
to those who know the addressing structure of the underlying machine. ]

5 A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer converted to an integer of sufficient size (if any such exists on the implementation)
and back to the same pointer type will have its original value; mappings between
pointers and integers are otherwise implementation-defined.

要するに規格としてはポインタ型を整数型にreinterpret_castして
その値をそのままポインタ型に戻す操作以外は完全に実装依存
627604:2005/05/22(日) 09:57:53
「5.2.10 Reinterpret cast」の真意は、整数型にキャストし、演算後の《変更された値》をポインタにキャストし戻したとしても、それはポインタとして無効であるということだけだと思うぞ。
一例を挙げると、配列の特定要素を指すポインタを整数型に変換した後、インスタンスオブジェクトのサイズ分だけ値を加算し、ポインタ型に戻したとしても、次の要素へのポインタにはならないぞ、、、という。

Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。
このため、上記の§5.2.10の規則には抵触しないと思うが?
むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。

integral typeにして何の演算も許さず、元のポインタに戻すことしかできないのであれば、そもそもキャストする意味ないし。 まさかシリアライズするのか?、、、ってそれはあまりにも危険だしな。
628デフォルトの名無しさん:2005/05/22(日) 10:18:14
>>626
ん?問題ないんじゃない?

同じポインタからは同じ整数になり、
同じ整数からは同じポインタになるっていう射影だよね。
この規格表のいいたいところは要するに、
アドレスが16違っている2つのポインタを、
整数に直した時も16違っているかどうかはわからないよ、
というだけの話じゃん。
629626:2005/05/22(日) 10:20:55
>>627
>Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。
>このため、上記の§5.2.10の規則には抵触しないと思うが?
>むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。

5.2.10/5はポインタを整数にreinterpret_castした後,その整数値を「そのまま何の演算も行わずに」
元のポインタ型に再度reinterpret_castした場合,元のポインタ値に復元されることを保証するものです.
604さんのmagic_listでは排他的論理和演算を取るため「そのまま」ではないものの
5.2.10/5は明らかにreinterpret_castによるpointer <-> integerの1対1写像を保証しているものと
読めるため確かにそのとおりですね.626は621に対する指摘のつもりでしたが,
いやはや指摘がまったく見当違いどころかむしろ621が正当である根拠になりえますね.
これまた大変失礼しました.

>>628
上に同じです.失礼しました.
630デフォルトの名無しさん:2005/05/22(日) 12:18:47
magic list はネタとしては面白いが、現実には滅多に使われない
データ構造だな。この手のネタは Hakcer's Delight とか Knuth
センセの本を読むとイロイロ転がってるよ。

あと、現実のプログラミングだと、list に int 一個だけ入れるのも
珍しい気がする。手元のコードをいくつか見直してみたが、わりと
大きめの構造体を繋ぐか、スマートポインタを入れることが多い。
いずれにしてもポインタ二個分のメモリなんて誤差って感じ。
631デフォルトの名無しさん:2005/05/22(日) 13:39:00
珍しいかどうかは、ともかく
メモリ云々行ってた奴は、たぶん初心者だから
初心者の戯言を、あまり真に受けないほうが
632デフォルトの名無しさん:2005/05/23(月) 09:43:55
結論はvector使え、でいいのか?
633デフォルトの名無しさん:2005/05/23(月) 09:54:29
>>632
いい
634デフォルトの名無しさん:2005/05/23(月) 12:40:40
magic list は所詮オナニー
635デフォルトの名無しさん:2005/05/23(月) 18:35:46
ここはジェネリックプログラミングの話題じゃないのか?
636デフォルトの名無しさん:2005/05/24(火) 00:13:26
>>635
テンプレートの話題ですよ。尤も、スレタイも読めないなら
このレスも読めない可能性、大。
637デフォルトの名無しさん:2005/05/24(火) 03:37:35
暇つぶしに作ってた、ヘボコンパイラは出来上がったから
今度は、マジックリストクラステンプレートでも作ってみようかな
作ったらほしい人いる?
638デフォルトの名無しさん:2005/05/24(火) 08:09:05
>>637 興味はある
639デフォルトの名無しさん:2005/05/24(火) 09:47:05
学術的な興味なら。
ソースより測定結果をみたい。listやvectorとの比較つきで。
640デフォルトの名無しさん:2005/05/24(火) 15:44:00
というか作りかけてる・・・
641デフォルトの名無しさん:2005/05/24(火) 22:41:55
できたら
>>639もぜひ。
642デフォルトの名無しさん:2005/05/24(火) 23:45:11
>>640
637だけど、あなたに任せます
643デフォルトの名無しさん:2005/05/25(水) 01:39:21
小規模だけど多次元配列のポインタがどうしても必要で、newも使いたくないから
std::vector<std::vector< ...> >
とかで書いてみたんだけど、4次元ぐらいからコンパイル時間が凄くかかる。
ま、コンパイル時に何がおきてるか想像すりゃ当たり前といえば当たり前だし、
コンパイル時だけの問題なので気にしなきゃいいんだけど、
環境になるべく依存しないで(boostとかは使えないし、VC,gcc両方通す必要あり)、
効率の良い方法がありまつかね。std::deque使ってもかわらなさそうだし。

644デフォルトの名無しさん:2005/05/25(水) 01:49:02
>>643
その「多次元配列」のインターフェースを必要最小限に絞って、
pimpl なり抽象インターフェースなりでコンパイル単位を分ける。
基本だな。
645デフォルトの名無しさん:2005/05/25(水) 02:06:06
>>644
dクス。
pimplイディオムは詳しくないので、Exceptional C++でも読んでみまつ。
646640:2005/05/25(水) 02:46:33
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/458.txt
面倒だったのでBoost使いました.1.32.0が必要です.すいません.
VC++7.1とGCC3.4.2(mingw)でコンパイル確認しています.
勢いだけで突っ走ったので激しく読みにくいコードで申し訳ないです.
イテレータが安定じゃないのでsplice系がイテレータ返さないと
使い物にならないので,イテレータ返すようにしてます.
std::listのインターフェースであと実装していないのはsortと演算子だけです.
でも今日はもう気力残ってません.パフォーマンス測定もしかりです.おやすみなさい.
647デフォルトの名無しさん:2005/05/25(水) 04:02:34
void reverse() // throw()
{
head_ = decode(sentry_.code, head_);
}

感動してしまった。
648デフォルトの名無しさん:2005/05/26(木) 03:43:21
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/468.txt
微妙なバカチョンと例外飛んだときのバグを直しました.多分これで完璧なつもりです.
ただ,相変わらずsortだけ面倒なので実装してないです.
指摘されていたこととは言え,このデータ構造イマイチ利点がぼやけてますね.
特にアラインメントの関係でノードのサイズが普通のリストのそれと
同じになってしまう(32-bitマシンでmagic_list<double>とか)場合もあったりで散々かも.
唯一,647さんが指摘されているように要素順の反転を定数時間でできるのが
大きな特色ですけれど,それがうれしい状況ってあるんでしょうか・・・.
649デフォルトの名無しさん:2005/06/06(月) 11:28:39
質問です。
「具現化によって生成された実体」 = 「ユーザー定義ではないスペシャライゼーション」
という理解でいいの?
650デフォルトの名無しさん:2005/06/07(火) 22:08:43
"template テンプレート パラメータ"の意味が理解できないッス。
"Modern C++ Design" P11 の以下のコードなんですけど、

template <template <class> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{
...
}

ここで template <class> に対して私の頭の中で
シンタックスエラーが発生します

template<class T> // ノーマル
template<> // 特殊化
template<class T=int> // デフォルト引数
template<class T, int=10> // 特殊化とデフォルト引数

というシンタックスは理解できています。
template <class> って何者? 誰か教えてください。
651デフォルトの名無しさん:2005/06/07(火) 22:12:38
省略されてるだけ。
template <class /*T*/>
class foo;
652デフォルトの名無しさん:2005/06/07(火) 22:27:41
>>651
サンクスです。とすると何らかの型を受け取るけど、
その型の情報は無視するよ、っていうことなんですね。
これをもとにもう一回読んでみます。
653デフォルトの名無しさん:2005/06/07(火) 22:32:56
>>650
int f(int i);
int g(int); // これも脳内エラーが出るか?
654デフォルトの名無しさん:2005/06/08(水) 00:28:08
>>650

例えば、

template< template<class T, class A> class Vector>
struct hoge
{
typedef T value_t;
};

typedef hoge<std::vector> hv_t;

としても、この時点では”T"はまだ決まってないわけだから
名前付けても使えないのです。
無論、”Vector"もこのままでは使えません。

実際の使用には

template< tempalte<class,class> class V>
struct hoge
{
template<class T,class A>
struct bind
{
typedef V<T,A> type;
};
};

typedef hoge<std::vector> hv;
typedef typename hv::template bind<int,std::allo..>::type
のように使うことになりますね。
655デフォルトの名無しさん:2005/06/08(水) 00:31:15
補足ですが、

使えない == typedefできないということです。
656デフォルトの名無しさん:2005/06/08(水) 00:41:11
>>654-655 とても650の理解を助けるとは思えない。
657デフォルトの名無しさん:2005/06/08(水) 01:10:19
間違ったことは言ってないが、質問の答えとしては完全にズレてるな。
658654:2005/06/08(水) 01:22:29
>>656-657

この場合
>"template テンプレート パラメータ"の意味が理解できないッス。
と書いてあるところから、名前云々は関係ないと思うのですが・・
659デフォルトの名無しさん:2005/06/08(水) 10:35:01
>>658 会話になってないな。もういいから喋るな。
660デフォルトの名無しさん:2005/06/08(水) 21:38:27
>>650です。
皆さんありがとうございます。
>>654さんのご意見もとても理解の助けになりました。
661デフォルトの名無しさん:2005/06/09(木) 08:01:15
typedf templateってどうなったの?
662デフォルトの名無しさん:2005/06/09(木) 08:13:16
template< template<class T, class A> class Vector>
struct hoge
{
typedef T value_t;
};
template<class B> typedef hoge<std::vector<B> > hv_t;
typeof(hv_t<int>::value_t) i;

みたいにtypedefの一文をテンプレート化できるんだっけ。
663デフォルトの名無しさん:2005/06/09(木) 08:32:30
>>662
それはだめだろ。
template-templateパラメタのtemplateパラメタ(この場合T)
に言及するのは意味的におかしい。
664デフォルトの名無しさん:2005/06/09(木) 08:43:39
こうじゃないか?

template <typename> struct hoge;
template <template <typename, typename> class V, typename T, typename A>
struct hoge<V<T, A> >
{
typedef T value_t;
};
template <typename T> typedef hoge<std::vector<T> > hv_t;
hv_t<int>::value_t i;
665デフォルトの名無しさん:2005/06/09(木) 08:49:01
typedef templateを導入するなら変数templateや名前空間templateも欲しい。

と無責任に言ってみるテスト。
666デフォルトの名無しさん:2005/06/09(木) 08:56:13
>>664
あーなるほど。C++よく分らないから適当に書いてみたんだけどそれなら理解できるw

>template <template <typename, typename> class V, typename T, typename A>
> struct hoge<V<T, A> >
こうやって部分的特殊化で各パラメータ間の関係を表現できるのね。

>>663
>template <typename T> typedef hoge<std::vector<T> > hv_t;

問題はこの部分で、パラメータvector<T>の高階性(?!)を維持してくれるのかどうかってところかねえ。

>>665
変数templateとはどんなもんでしょ?
667デフォルトの名無しさん:2005/06/09(木) 11:34:08
もしも変数テンプレートがあったとしたらこんな感じ?
template <typename T> const T *NULL = 0;

int *pi = NULL;
char *pc = NULL;

#include <cstdio>
int main() {
  std::printf("%p", NULL<void *>);
}
668デフォルトの名無しさん:2005/06/09(木) 11:59:30
>>667
>int *pi = NULL;
>char *pc = NULL;
これを許すとまた規則が複雑になるな。
669デフォルトの名無しさん:2005/06/09(木) 12:14:33
class null {
public: template<typename T> operator T*() const { return 0; }
};

const null NULL;

int *ip = NULL;
char *cp = NULL;

printf("%p", (void*)NULL);

でいいような気がす
670デフォルトの名無しさん:2005/06/09(木) 12:16:52
誰もそんな話ししてないわけだが
671デフォルトの名無しさん:2005/06/09(木) 13:24:53
>>667
引数とるコンストラクターはどうなるんだ。
672デフォルトの名無しさん:2005/06/09(木) 13:52:48
typedef template ムチャ欲しいな。
673デフォルトの名無しさん:2005/06/09(木) 14:26:04
>>667
今のC++の型の取り扱いにあわせると

template<typename T> const T *NULL = 0;

は,右辺がリテラルの0でこれは型がintだからポインタ型に変換できず,
Tをどの型でinstantiationすれば良いのか判断できずコンパイルエラーになる,
っていう扱いが妥当だと思いますよ.
もうちょい厳密に変数テンプレートを定義しようとすると,
結局,型推論のためのautoキーワードの拡張

auto a = b; // typename(b) a = b; の構文糖

と同じになると思います.Andrew Koenigあたりがこのautoキーワードの代わりに
>>667の構文を提案してたはず.
674デフォルトの名無しさん:2005/06/09(木) 14:35:13
>>673
>>667の代わりに、
template <typename T> struct wrap{static const T *null;};
template <typename T> const T *wrap<T>::null = 0;
と書けることを考えると、今の扱いなら、

・template <typename T> const T *NULL = 0;
の時点では何も起こらない。
・printf("%p" NULL<void *>);
の点でインスタンス化が引き起こされ、void *const *を0で初期設定しようとし、成功。

が妥当じゃないのか?
675デフォルトの名無しさん:2005/06/09(木) 14:50:45
>>670
そうでなくて、必要性が全く感じられないと言っている
まともな利用例ぐらい出さないと
676デフォルトの名無しさん:2005/06/09(木) 14:56:07
>>674
その使い方だと常に明示的にインスタンス化しないといけない
(NULLを利用するたびに型パラメータを与えないといけない)わけですよね?
それは利用範囲が著しく限られませんか?
677667:2005/06/09(木) 15:03:10
ところで俺は変数テンプレートは全く要らないと思うんだけどな。
俺も669と同じようなのを考えたことはあるけど。
678デフォルトの名無しさん:2005/06/09(木) 15:10:28
>>676
使い道がないのは同意。
ただ、仮に現在のテンプレートの延長で「変数テンプレート」なるものを定義するなら、
>>674で言ったようになるはずだと思った。
>>673のような機能を導入するなら別の名前・構文を考えるべきだと思う。
679デフォルトの名無しさん:2005/06/09(木) 15:26:38
型推論はされるとして、
NULLみたいに初期化子に使うとちょっと面白そうな…

クラス階層のあるところでPTHREAD_MUTEX_INITIALIZERみたいなやつ。
680デフォルトの名無しさん:2005/06/09(木) 15:29:21
>>678
確かに「変数テンプレート」という名前は非常にまずいですね.
ただ構文については既存のキーワード使うとするとこれぐらいしかないような気がします.
681デフォルトの名無しさん:2005/06/12(日) 15:01:48
アドビのオープンソースってど?流行ると思う?
STL、boostを基に、ウィンドウをスクリプトから生成する画期的システム
仮想マシンを実現とか、内容は理解を超えていた (つД`)

いわゆるチョット修正のときに威力を発揮すると思う
SEはどんな些細なこともPGに要望しなけりゃならない
PGは思いつきの修正のために仕事が増えるばかり
だれか人柱になってください、やっぱアドビ待ちなのかな
682デフォルトの名無しさん:2005/06/12(日) 17:16:13
>>681
AdamとEve( ttp://opensource.adobe.com/ )のことか?なかなか
普及は難しいんじゃないかなぁ…
683デフォルトの名無しさん:2005/06/13(月) 00:40:41
質問です。
BCC 5.5上のテンプレートのバグはどのようなものが
あるのでしょうか。

・・・特に大きいタイプリストを渡すと、他の特殊化に指定
したクラスが別のクラスに化けるとか、そんなのないですか?
684デフォルトの名無しさん:2005/06/13(月) 10:45:49
>>683
質問するときはやりたいこと、実際にやったことを書いた方が良い。
685デフォルトの名無しさん:2005/06/13(月) 14:20:43
>>683
どういうバグかは知らんがboostが満足に使えない。
686683:2005/06/13(月) 21:39:52
自己解決しちゃいました。

経緯だけ説明しますと、Modern C++ Designのマルチメソッドを
自分の使いやすい形に改良して使っていたんです。で特殊化の
際タイプリストを
template<..,class Head,class Tail>struct
Dispatcher<...,Typelist<Head,Tail>,...>{
...省略
};
と展開していて、6ほどの長さのタイプリストをわたしたところエラー吐かれました。
(5つまでは普通にコンパイル&動作しました)

これを
template<..,class TList>struct
Dispatcher<...,TList,...>{
...省略
};
としHeadにアクセスするときTList::Head,Tailにアクセスするときは
TList::Tailとするようにしたら今度は何十の長さでもコンパイルできました。

前者のコンパイルの仕方にバグがあるんでしょうかね・・・
687デフォルトの名無しさん:2005/06/13(月) 23:51:10
BCCなんか使うなよ
688デフォルトの名無しさん:2005/06/14(火) 17:45:57
もしかして、クラステンプレートのメンバ仮想関数って勝手に実体化される?
689デフォルトの名無しさん:2005/06/14(火) 17:58:42
>>688
どんなコードでそう思った?
690688:2005/06/14(火) 18:10:23
ものすごく単純化すると、
class base
{
public:
virtual void foo() = 0;
};
template <class> class derived : public base
{
public:
virtual void foo() { std::cout << "呼ばれた\n"; }
};
int main()
{
derived<int> d;
static_cast<base&>(d).foo();
}
こんな感じ。
691デフォルトの名無しさん:2005/06/14(火) 18:24:16
>>690
それってderived<int>型の変数dを宣言したからderived<int>が実体化されているだけのように見えるが。
692688:2005/06/14(火) 18:28:53
derived<int> が実体化されるのと
derived<int>::foo が実体化されるのは別じゃないですか?
クラステンプレートのメンバって呼ばれるまで実体化されませんよね?
693デフォルトの名無しさん:2005/06/14(火) 18:31:57
>>688
規格では詳しくは規定されていないっぽい。
実際は
・derived<int>のインスタンスが宣言された
・derived<int>*からbase*の変換が行われた
のいずれかをトリガとして、仮想関数をすべて実体化することになると思う。
694688:2005/06/14(火) 18:40:33
>>693
サンクス。未定義ってことですか。
一応、明示的に実体化しておいたほうがよさそうですね。
695デフォルトの名無しさん:2005/06/14(火) 18:47:45
>一応、明示的に実体化しておいたほうがよさそうですね。
なんでそうなる?

ついでに、「未定義」と「未規定」は違う。
696688:2005/06/14(火) 18:50:17
ん?
規定はされていなくても、正常に動くことは保証されているってことですか?
697693:2005/06/14(火) 18:57:55
言い方が不正確だったな。
規格には、「メンバ関数は、その定義が必要とされるとき実体化される(意訳)」とある。
で、virtual関数については、いつ「定義が必要とされる」か正確に規定している部分が(俺の見た限りでは)なかった。
従って、virtual関数の正確な実体化のタイミングは規定されていないことになる。
それでも、「必要」になり次第実体化されることは保障される。
698688:2005/06/14(火) 19:22:06
あー、なるほど。
規定されていないのは実体化されるタイミングだということですね。
どうもありがとうございました。
699デフォルトの名無しさん:2005/06/26(日) 18:25:16
int k = 0;
for (vector< set<int> >::iterator it = v.begin(); it != v.end(); ++it)
it->insert(k++);

を boost::lambda か何かを使って for_each でシンプルに書けませんか?
メンバー関数に bind する仕方がよく分からないんですが・・・
700デフォルトの名無しさん:2005/06/26(日) 19:33:36
>>699
typedef std::set< int > set_type;
typedef std::vector< set_type > vector_type;
void f( vector_type& v )
{
 using namespace boost::lambda;
 int k = 0;
 std::for_each(v.begin(), v.end(), (protect(bind((std::pair<set_type::iterator,bool> (set_type::*)(int const&))(&set_type::insert), _1, var(k)++)))(*_1));
}

○ boost::lambda か何かを使って
○ for_each で
× シンプルに
701700:2005/06/26(日) 19:49:39
メンバ関数に限らず、オーバーロードが絡むと lambda は使いにくいな。
702デフォルトの名無しさん:2005/06/27(月) 06:52:07
protect要るか?

>>701
C++は名前が重なった場合の簡潔な指名定方法がないしね。
lambdaに限らず面倒。
typeofがBoostに入るそうだから、そのうち頑張って改善されるといいな。
703700:2005/06/27(月) 07:50:29
>>702
こんな感じで変形していったが、途中のやつの
エラーメッセージがひどくて(数100行ぐらい出る)、
何がまずかったのかよくわかってない。
× ((*_1)->*insert)(var(k)++)
× bind(insert, *_1, var(k)++)
○ (protect(bind(insert, _1, var(k)++)))(*_1)
704702:2005/06/27(月) 22:11:02
>>703
その3つの最初から間違ってるよ。
for_eachなんだから_1にはイテレータではなく参照が入る。よって
_1をdereferenceする必要はない。

まあ同じなんだけど、俺ならオーバーロードが絡む場合は
メンバ関数の特定を追い出すかな。
void hoge(vector<set<int> >& v) {
    typedef set<int> set_type;
    pair<set_type::iterator,bool>(set_type::*insert)(const int&)
        = &set_type::insert;

    int k = 0;
    for_each(v.begin(), v.end(), bind(insert, _1, var(k)++));
}
705700:2005/06/28(火) 00:20:42
>>704
うわ、とんでもない勘違いをしていたよ。
ありがとう。
706デフォルトの名無しさん:2005/07/05(火) 14:15:55
ttp://d.hatena.ne.jp/soleil/searchdiary?word=%2a%5b%c5%fd%b7%d7%5d
ここに書いてあった
struct Mean
ってどう使うの? 例がないと分からない
functorなのは分かったけど
707デフォルトの名無しさん:2005/07/05(火) 14:27:54
int array[] = {1, 3, 5};
std::vector<double> v = ...;

int ma = Mean<int *>()(array, array + 3);
double mv = Mean<std::vector<double>::iterator>()(v.begin(), v.end());

こんな感じじゃないか?
708デフォルトの名無しさん:2005/07/05(火) 16:19:10
for_eachにかけるものではないのね
でも便利そう thx
709デフォルトの名無しさん:2005/07/05(火) 16:25:40
>>707
のとおりにやってみたけど
コンパイル通らなかったよ
710デフォルトの名無しさん:2005/07/05(火) 17:04:14
>>706
> 算術平均を求める Mean を書き直すと以下のようになる
> (もちろん Sum も反復子を使うように変更してあることが前提)

ちゃんとSumもコード書いた?

んで、漏れなら、合計値(累積値)を求めるアルゴリズムaccumulateを使い
平均値は:

void f(vector<double>& m) {
double avg = accumulate(m.begin(), m.end(), 0.0) / m.size();
}

のようにして求めるな。分散・標準偏差、RMSあたりも似たような実装ができる。
711デフォルトの名無しさん:2005/07/06(水) 04:42:18
>>710
わざわざ関数にするのか?
コードの大きさを抑えるのにはいいけど。
712デフォルトの名無しさん:2005/07/06(水) 07:22:20
>>711
しない。入力が何で出力が何か明確にしたかったので、関数形式で書いただけ。
実際に関数にするなら、template、inline、引数にはconst、戻値の型を明記、あたりが必要です。

蛇足で糞コード晒す。
template <typename T>
struct square : public binary_function<T, T, T> {
T operator()(const T& lhs, const T& rhs) { return lhs + rhs*rhs; };
};

double ms = accumulate(m.begin(), m.end(), 0.0, square<double>()) / m.size();
double rms = sqrt(ms);
double stdev = sqrt(ms - avg*avg);
713デフォルトの名無しさん:2005/07/06(水) 08:07:25
STLは連続した、同じような事の繰り返し処理には滅法強いな。
714デフォルトの名無しさん:2005/07/06(水) 20:49:48
>>713
あなたの人生もSTLで簡単になりますよ。

void silly_life(life& your_life)
{
  struct
  {
    static int daily(day& d)
    {
      d.nebou();
      d.nichan();
      d.onanu();
      d.shigoto();
      d.nichan();
      d.onanu();
      d.neru();
      return 0;
    }
  };

  std::for_each(your_life.begin(), your_life.end(), daily);
}

久しぶりにtemplate見たよ。。。C#使いづれ〜。。。orz
715デフォルトの名無しさん:2005/07/07(木) 00:00:05
それがSTLクオリティ。

語呂悪いな。
716デフォルトの名無しさん:2005/07/07(木) 07:31:19
速度が重要になるコードを書かなければなのですが、
やはりSTL経由の連続処理は、速度的に不利なんでしょうか?

一応自分なりに、次レスに書いたような実験をしてみたのですが、
プロファイル結果はSTL版hoge()が平均301msに対し、
シンプルなリストhage()の方が平均12msと、圧倒的な差に…。

今更自前リストなんて使うのは、考えただけで頭が痛くて。
なにかテストに落ちがないか、
或いはSTL版速度向上のための抜け道が無いか、教えて頂けないでしょうか。
#include <list>
struct simple_list{
int val;
simple_list* next;
};
template <typename T>
void hoge( T first, T last ){
int sum = 0;
while( first != last ) sum += *(first++);
};
void hage( simple_list* sl_first ){
int sum = 0;
while( sl_first ){ sum += sl_first->val; sl_first = sl_first->next;}
};
int main(){
std::list<int> listInt;
for( unsigned long i=0; i < 100000; ++i ) listInt.push_back(i);

simple_list* sl_first = new simple_list;
simple_list* sl = sl_first;
for( unsigned long c=0; c < 100000; ++c ){
sl->val = c;
sl->next = new simple_list;
sl = sl->next;
}
sl->next = NULL;

hoge( listInt.begin(), listInt.end() );
hage( sl_first );
while( sl_first ){ sl = sl_first->next;delete sl_first; sl_first = sl; }
return 0;
}
718デフォルトの名無しさん:2005/07/07(木) 07:51:04
>>716
プロファイルでは最適化は有効にしてる?
最適化しないと比較にならないし、最適化すると hoge(), hage() が
sum を返してないので、最適化で処理自体が消えてダメかもしれない。

hoge の sum += *(first++); を { sum += *first; ++first } にすると、少し違うかもしれない。
719デフォルトの名無しさん:2005/07/07(木) 07:51:41
>>716
最適化した?
うちじゃ
hoge(): 8.46567 ms
hage(): 7.92051 ms
くらいなんだけど
環境はg++ (3.3.5)
720716:2005/07/07(木) 08:08:12
我ながら非道い
sl->next = NULL;を削って
sl->next = new simple_list; を
sl->next = (c != 100000-1) ? new simple_list : NULL; とでも

>>718-719
最適化をすっかり忘れていました。
なぜだかsumを返すようにしてもhogeの方が消えてしまうのですが
もう少し試行錯誤してみます。

いずれにせよ力づけられました。ホッとしています。
レスありがとうございました。
721デフォルトの名無しさん:2005/07/07(木) 08:20:05
>>720
返すだけで戻り値を使ってないんじゃ、と消えるかもしれないな。
チェックもかねて、画面に値を出すようにすれば大丈夫じゃない?
(そこまでやっても、ただの定数に置き換えてしまうコンパイラとかあるかもしれない。)

最終的にはアセンブリを吐かせて確認するといい。
722716:2005/07/07(木) 08:25:49
最適化無しで719さんの方法で15%ほど速く
>>721
もしかしたらtemplateだったせいかも知れないです。インライン化されていたのかな。
templateを外したらhogeも出ました

hoge: 5.579 ms
hage: 5.313 ms
(vc++6)

朝からお騒がせしました、お二人(三人?)に再度感謝です
723デフォルトの名無しさん:2005/07/07(木) 08:31:10
その程度の処理だとlistは兎も角、vectorは普通の配列と全く同じ速度出るよ。
#つーか、gccでもVC++でもstlの有無で全く同じ(質の)コード吐くんだけどね。
724デフォルトの名無しさん:2005/07/07(木) 18:13:33
>>723
VCだと
vector>=配列
になるときもない?(誤差範囲内だけど)
GCCは
vector使うと少し遅くなる気がした。
725デフォルトの名無しさん:2005/07/07(木) 18:23:22
その辺は具体的なコードを提示して比較でもしない限りなんとも言えないなぁ。
そもそも最適化で消えないコードでって条件になっちゃうし。
726デフォルトの名無しさん:2005/07/07(木) 18:30:29
vectorのiteratorは大抵の処理系/STL実装で非デバッグ時には単なるポインタだろ。
727デフォルトの名無しさん:2005/07/07(木) 18:34:16
>>722
ちなみに std::list が double-linked list だということは知ってるよな
728デフォルトの名無しさん:2005/07/07(木) 23:52:14
doubleじゃないSTLのlistを提示しない限りそのレスは無意味
729デフォルトの名無しさん:2005/07/08(金) 00:55:24
>>728
おれは>727じゃないけど、なんで?
730デフォルトの名無しさん:2005/07/08(金) 01:02:35
そういえばslistは標準じゃないんだな。 STLPortにはあるけど。
731デフォルトの名無しさん:2005/07/08(金) 20:43:04
次のようなコードがあるとします:
 struct base1 { base1(int x) {}; };
 struct base2 { base2(int x, int y) {}; };

 // IF<P,T,F>クラステンプレートは、Pが非0のときT、0のときFをIF::typeにtypedefする
 template <int N> struct derived : public IF<N,base1,base2>::type {};

このとき引数の数が異なるコンストラクタを持つ基底クラスをテンプレートで切り替え、
派生クラスのコンストラクタから、基底クラスのコンストラクタを呼び出したいのです:
 derived<1> d(0); // base1から継承し、コンストラクタは引数1
 derived<0> d(0, 1); // base2から継承し、コンストラクタは引数2

基底クラスのコンストラクタを呼び出すときには、派生クラスの初期化リストを使います。
ところが、派生クラスのコンストラクタ初期化リストでは、基底クラスのコンストラクタ
以外呼べませんから、次のように多重定義できません:
 // Nが非0だとすると
 derived(int x) : base1(x) {};
 derived(int x, int y) : base2(x, y) {}; // error! 基底クラスはbase1

このように基底クラスをテンプレートで替える場合に、うまく派生クラスのコンストラクタの
引数の数を調整するようなテクニックがあれば、ご教示いただけると幸いです。
また、異なるアプローチもあればコメントください。
732デフォルトの名無しさん:2005/07/08(金) 20:50:10
俺にはderivedをNの値によって特殊化する方法しか思いつかない。
733デフォルトの名無しさん:2005/07/08(金) 22:22:17
試しにこう書いてみたら g++ 3.4.4 cygming special では通ったんだが。

derived(int x) : IF<N,base1,base2>::type(x) {}
derived(int x, int y) : IF<N,base1,base2>::type(x,y) {}
734731:2005/07/09(土) 02:41:09
>>732-733
レスありがとうございました。
>733の方法で、パパ、うまくできそうです。
続きがんばります!
735デフォルトの名無しさん:2005/07/09(土) 08:17:21
どうもネットの世界の「ご教示」とか「ご教授」って浮いた言葉だなぁ。
736デフォルトの名無しさん:2005/07/10(日) 00:59:18
実は初めてこの構文を知ったんだけどさ

>ttp://www.comeaucomputing.com/techtalk/templates/#esprobs
>
>template <class T>
>T foo(T blah)
>{
>    xyz object;
>    T someInt;
>
>// (略)
>
>    someInt = object.mt<int>(99.99); // AA: ill-formed
>    someInt = object.template mt<int>(99.99); // BB: well-formed
>
>    return someInt;
>}

ってなってて AA は ill-formed になってるんだけど、 object はテンプレートパラメータに依存してないんだから
template をつけなくても問題ないと思うんだけど。実際 g++ 3.4.4 だと通るし、. の前をテンプレートパラメータに
依存するように書き換えるとエラーが出る。

規格参照箇所 14.2-4
> When the name of a member template specialization appears after . or -> in a postfix-expression, or after
> nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a
> template-parameter (14.6.2), the member template name must be prefixed by the keyword template.
> Otherwise the name is assumed to name a non-template.
737デフォルトの名無しさん:2005/07/10(日) 02:07:52
template <typename T>
class Hoge {
public:
typedef std::vector<T> Container;
typedef Container::iterator Iterator;

private:
Container v;
};

と書いて、Hoge<int> hoge; とか呼ぶと、implicitなtypenameだと警告を言われます。
iteratorを表現するにはどのように記述すべきなのでしょうか。
738デフォルトの名無しさん:2005/07/10(日) 02:09:19
>>737 gcc version 3.2 20020927 (prerelease) です。
739737:2005/07/10(日) 02:11:47
http://www.tietew.jp/cppll/archive/10073 によると、

typename Container::iterator Iterator;

と書くみたいですね。これって常識なのかしら。
740デフォルトの名無しさん:2005/07/10(日) 02:27:11
>>739
その場合、typenameは必須。
741デフォルトの名無しさん:2005/07/10(日) 02:36:16
常識
742デフォルトの名無しさん:2005/07/10(日) 04:36:52
当然
743デフォルトの名無しさん:2005/07/11(月) 10:24:40
>>739
特殊化があるC++では、Tが確定しないと型推論が困っちゃうんで、
typedef typename Container::iterator Iterator;
って感じで。
typename Container::iterator Iterator;
も可能。
Container<int> v;
なら何とかなるはずだけど、explicitにtypenameしましょうという仕様。
744デフォルトの名無しさん:2005/07/16(土) 20:53:42
>型推論が困っちゃう

そうなのか?
Tが確定しないと、特殊化のあるC++ではstd::vector<T>::iteratorが
typedefされた型名か、メンバ(メンバ変数・関数)かが分からないから
コンパイラへのヒントとして型名であることを明示するのを義務付けてるんでは?
745デフォルトの名無しさん:2005/07/19(火) 22:11:08

全然わかってないけど質問します。

テンプレートクラスの実装って全てヘッダーでやらないといけないんですか?
.cppの方でやるとリンカーエラーが出てリンクできないのですが!?
(全部ヘッダーにコピペしたら通った)
746デフォルトの名無しさん:2005/07/19(火) 22:14:53

追加

だが、しかしそれをやると2重定義になる…
どうすればいいんじゃーーーー
747デフォルトの名無しさん:2005/07/19(火) 22:20:05
>>745
テンプレートの定義をcppファイルに書きたければ、宣言と定義の両方にexportを付けるだけ。
しかしほとんどのコンパイラで使えない。(使えるコンパイラが全くないわけではない)

というわけで普通はヘッダにインラインで全て書く。
ごく稀に明示的実体化が使われることはあるが。
748デフォルトの名無しさん:2005/07/19(火) 22:48:35
>>747
明示的実体化ってまさか、

template class c<bool>;
template class c<char>;
template class c<unsigned char>;

みたいに延々と cpp ファイルに書いていくわけ?
749デフォルトの名無しさん:2005/07/19(火) 23:06:05
g++にはextern templateってのがあるね。
750デフォルトの名無しさん:2005/07/19(火) 23:11:50
>748
そゆこと。
751745:2005/07/19(火) 23:17:21
やってみた>>747

make -k all
g++ -Wall main.cpp Class.cpp -c
g++ -Wall main.o Class.o -o a.exe
main.o(.text+0x25):main.cpp: undefined reference to `Class<int>::Class[in-charge]()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

ムリポ

>>749を含めて出直してくる。これはイマの私の頭ではいくら考えても答えが出ない。
本を読むかg++のマニュアルを漁るか…
752デフォルトの名無しさん:2005/07/19(火) 23:44:58
>>751
g++のinclude/bits/istream.tccより

// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
#if _GLIBCPP_EXTERN_TEMPLATE
extern template class basic_istream<char>;
extern template istream& ws(istream&);
extern template istream& operator>>(istream&, char&);
extern template istream& operator>>(istream&, char*)
753デフォルトの名無しさん:2005/07/23(土) 19:33:12
template <class T> class foo;

template <class T> class baa{
 friend foo;
 int n;
public:
 baa() : n(777){}
};

template <class T> class foo : public baa<T>{
 int hoge;
public:
 void set_val( baa<T>& arg ){ hoge = arg.n; }
};

int main(){
 baa<int> b;
 foo<int> f;
 f.set_val( b );
 return 0;
}

インデントが全角スペースですいません
これだとarg.nにアクセス出来ないのですが、間違っている場所を教えて頂けないでしょうか
friend foo; が、やっぱり
template <class T> friend foo; なんでしょうか
754デフォルトの名無しさん:2005/07/23(土) 19:45:24
>>753
g++ でコンパイルすると、
:4: error: ISO C++ forbids declaration of `foo' with no type
:4: error: `foo' is neither function nor member function; cannot be declared friend

まぁそれは置いとくとして、
 friend class foo<T>;
で通ったよ。
755753:2005/07/23(土) 19:59:42
>>754
やっぱりclass指定しますよね
書き込む前にチェックしたサイトで、指定が無かったので、自分が間違っていたのかと

そうか、再度template <class T>付けるのは馬鹿でした。
VC6なので、Tが同じじゃなかったらアウトだったかも・・・良かった。

本当に助かりました。コンパイルまでして頂いてすいません。ありがとうございました。
756デフォルトの名無しさん:2005/07/23(土) 20:13:13
baaっての…なんかプログラムがアホっぽくなるな。
757デフォルトの名無しさん:2005/07/23(土) 22:22:39
>>755
friend かどうかっていう問題なのか?
baa<T>::n が private か protected/public かどうかっていう問題では?
758デフォルトの名無しさん:2005/07/23(土) 22:47:57
>>757
vtableを避けるための小細工なんです
眉をしかめる人が多いと思いますが、自分しか使わないのでお見逃しを
759デフォルトの名無しさん:2005/07/23(土) 23:36:56
>>758
よくわからないな。>>753 のを
template <class T> class baa{
protected:
 int n;
public:
 baa() : n(777){}
};
とすると VC6 だと vtable に関して状況が変わるの?
760デフォルトの名無しさん:2005/07/23(土) 23:51:14
753がprotectedを知らなかったというオチ?
761デフォルトの名無しさん:2005/07/24(日) 00:21:24
>>759
失礼、深読みしすぎてました。

しかしすいません、そうなると>>757で頂いたレスの意図が分からないです。
protectedすると、引数で他のbaaを受け取ったとき、nにアクセス出来るのでしょうか。
762760:2005/07/24(日) 00:40:00
753のコードでは、bar<T>::nがprotectedならfoo<T>::set_valの中でarg.nにアクセスできると思っていたがそうではなかったようだ。
スマソ
763デフォルトの名無しさん:2005/07/24(日) 01:03:17
>>761
アクセスできると思ってた。けど間違ってたのなら失礼。
・基本 class から 派生 class を public 継承したとき、
・基本 class の protected member である n について、
・派生 class から this の n にアクセスできる。
・派生 class から this 以外の n にアクセスできない。
ということかな?も一回勉強しなおそ。

・ある class の private member である n について、
・その class から this の n にアクセスできる。
・その class から this 以外の n にアクセスできる。
というのは間違いないと思うんだけど。

あと自分の VC7 は、これに関して template class かそうでないかによって
コンパイル結果が違うのもよくわからない。
764デフォルトの名無しさん:2005/07/24(日) 02:17:54
勉強しなおした。>>763は間違い多数につきスルーよろしく。失礼しますた。
765デフォルトの名無しさん:2005/07/28(木) 18:38:46
Compile-time if
で型でなく値を返すにはどうすればいいのでしょうか?
int v= boost::mpl::if_c< (sizeof(T) <= sizeof(double)), 10, 20 >::Value
はだめでした
766デフォルトの名無しさん:2005/07/28(木) 19:41:12
>>765
boost::mpl::int_
を使って、型にマップすればいい。
767デフォルトの名無しさん:2005/07/28(木) 19:56:38
>>765
struct R0 {
enum {value = 10};
};
struct R1 {
enum {value = 20};
};
template <typename T>
int func ()
{
typedef typename boost::mpl::if_c <(sizeof (T) <= sizeof (double)), R0, R1>::type Result;
return Result::value;
}
768デフォルトの名無しさん:2005/07/29(金) 10:42:43
template<CONTANER>
class CmyContaner
{
typedef CONTANER::iterator iterator_type;
};
としたらコンパイル通らなかったんですが、
CONTANER::iteratorはできないってことなのでしょうか?
769デフォルトの名無しさん:2005/07/29(金) 11:35:24
>>768
-typedef CONTANER::iterator iterator_type;
+typedef typename CONTANER::iterator iterator_type;
770デフォルトの名無しさん:2005/07/29(金) 15:37:41
そのままじゃ型名かメンバ変数かわからんからね。

> CONTANER
北斗の拳の主題歌を思い出すスペルミスだな。
771デフォルトの名無しさん:2005/07/29(金) 16:46:27
>>768
ここもだね
-template<CONTANER>
+template<typename CONTANER>
772デフォルトの名無しさん:2005/07/30(土) 08:40:48
template<Functor>
class MyMethod
{
public:
Functor f_
MyMethod(Functor f):f(f_)
{}
value()
{
f_(10);
}
};

class MyClass
{
public:
struct MyFunctor{
operator()(int a)
{
std::cout << a;
}myFunc;

//MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない
MyMethod<MyFunctor> myMethod(MyFunctor);//なぜかコンパイル通る
value(){
myMethod.value();//左側がクラス 構造体 共用体でありません と怒られる
}
};

クラスの中でfunctorを定義したら動かなくなりました。
回避方法はないのでしょうか?
773デフォルトの名無しさん:2005/07/30(土) 09:48:49
>>772
>クラスの中でfunctorを定義したら動かなくなりました。
クラスの外でfunctorを定義したらそれ動く?
774デフォルトの名無しさん:2005/07/30(土) 13:47:17
>772
とりあえず } が 1 個足りない。
} myFunc; の前に 1 個ある、でいいのか?

>MyMethod<MyFunctor> myMethod(MyFunctor);
これだと MyFunctor 型の引数をとり、MyMethod<MyFunctor> 型を返すメンバ関数 myMethod を
宣言しているんじゃまいか?

>//MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない
なんでメンバ変数を宣言してるのに初期化しようとしてるの?

MyMethod<MyFunctor> myMethod;
MyClass() : myMethod(myFunc) {}

じゃねーのか?あと↑だと myFunc との初期化順序が問題になる場合があるかも。
今回の場合、MyClass() : myMethod(MyFunctor()) でいいような気もするが。
775772:2005/07/30(土) 14:59:26
すみません } が1つぬけてました。

template<Functor> class MyMethod
にclass の外で定義したfunctorを使うと
意図したとうりの動きをすることを確認しています。
776デフォルトの名無しさん:2005/07/30(土) 15:06:57
>>775
>class の外で定義したfunctorを使うと
>意図したとうりの動きをすることを確認しています。
本当に?
コピペにかなりミスがあると思うよ
MyMethod::value()
MyClass::MyFunctor::operator()(int a)
の返値の型は?

もし本当に動くなら処理系を教えてね
777776:2005/07/30(土) 15:09:07
たぶんこんなことしたいのかな
template <typename Functor>
struct MyMethod {
Functor f_;
MyMethod (Functor f): f_(f) {}
void value () {f_ (10);}
};
struct MyClass {
struct MyFunctor {
void operator () (int a) {
std::cout << a;
}
} myFunc;
MyMethod <MyFunctor> myMethod;
MyClass (): myFunc (), myMethod(myFunc) {}
void value() {myMethod.value();}
};
778デフォルトの名無しさん:2005/08/02(火) 22:23:20
template<X>
class CHoge
{public:
CHoge( X= typeof(x) ) {}
};
なんてできないの?
自動で型判別してほしい。
自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど
779デフォルトの名無しさん:2005/08/02(火) 23:18:35
>>778
>自動で型判別してほしい。
>自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど
これらはできるけど
例で何がしたいのかさっぱり分かりません
780デフォルトの名無しさん:2005/08/05(金) 23:15:18
template< ArrayType >
function( ArrayType array)
{
Compile-time If (ArrayType はポインタの配列?)
{
int a= array[0]->value;
}else{
int a= array[0].value;
}
こんなことがしたい
781デフォルトの名無しさん:2005/08/05(金) 23:30:47
type_traitsでいいんじゃないの?
782デフォルトの名無しさん:2005/08/06(土) 00:52:15
個人的には値の配列とポインタの配列を静的多相に扱おうとする行為そのものに
異議を申し立てたい.
783デフォルトの名無しさん:2005/08/06(土) 02:36:31
次のようなコードが、Visual C++では通るけどGCCでは通りません。

オブジェクトの名前と番号の型を保持する構造体を用意

template<class S,class I>
struct Types
{
  typedef S String;
  typedef I Integer;
};

この定義を受け取って型を定義するベースクラスを作成

template<class T>
struct Base
{
  typedef typename T::String StringType;
  typedef typename T::Integer IntegerType;
};

そして、これを利用するサブクラスを作成。

template<class T>
struct Derived : public Base<T>
{
  StringType name; //!< ここでコンパイルエラー
  IntegerType number; //!< 同様
};

typedef Types<std::string,int> StdTypes;
Derived<StdTypes> derived;
784デフォルトの名無しさん:2005/08/06(土) 02:38:23
続き

以下のように書けばGCCでもコンパイルは通ります。

typename Derived::StringType name;
typename Derived::IntegerType number;

こんな面倒な書き方しかできないなら、
わざわざベースクラスにtypedefした意味がないんですが
何かいい方法ありませんか?
785デフォルトの名無しさん:2005/08/06(土) 02:58:54
>>783-784
Base の定義中に typename が必要な理由を知っていれば、無理だと予想が付くだろうに。
786デフォルトの名無しさん:2005/08/06(土) 07:54:33
>>783-784
俺だったら
Base::Stringと書けないか
Derivedの中にusing Base::String;と書けばStringが使えないか
の2つをまず試してみる。これでできるかどうかはもちろんしらんが。
787デフォルトの名無しさん:2005/08/06(土) 09:04:33
Baseを使うなら、
typename Base<T>::StringType name;
typename Base<T>::IntegerType number;
こうなるから、これこそ、
> わざわざベースクラスにtypedefした意味がない
ので、>>784のやり方が良いだろう。

VC++もそのうち>>783は駄目になることでしょう。
788デフォルトの名無しさん:2005/08/06(土) 09:32:41
>>784
それVC7.1のバグらしい。
面倒見が良すぎて、typenameを本来ならば書かなければならない
所を、曖昧さがない場合は無くても通してしまう。

VC7.1でもちゃんと typename は書くべき。
789デフォルトの名無しさん:2005/08/06(土) 12:59:29
このスレの難読コードをみて
おれにとて


C++はなかたことになた
790デフォルトの名無しさん:2005/08/06(土) 13:03:53
そんなだから、未だに君にとってこの程度が「難読コード」なんだよ。
791デフォルトの名無しさん:2005/08/06(土) 13:07:40
俺もtemplateのコードは可読性が低いと思うよ
唯一の弱点だな
792デフォルトの名無しさん:2005/08/06(土) 13:32:35
テンプレートとC++「本体」って明らかに別の言語だよな。
概念の異なる2つの言語が混在してるんだから、
可読性が低いのは当たり前。
793デフォルトの名無しさん:2005/08/06(土) 15:19:32
>>792
じゃあどういう構文にすればいいよ?
794デフォルトの名無しさん:2005/08/06(土) 19:15:56
構文の話なのかな。
795デフォルトの名無しさん:2005/08/06(土) 19:21:27
>>784
template<class T>
struct Derived : public Base<T>
{
typedef Base <T> Base_;
typedef typename Base_::StringType StringType;
typedef typename Base_::IntegerType IntegerType;
StringType name;
IntegerType number;
};
796デフォルトの名無しさん:2005/08/06(土) 20:27:48
>>795 意味無いじゃん。
797神゜:2005/08/06(土) 20:49:53
そろそろ俺の出番か?
798デフォルトの名無しさん:2005/08/06(土) 21:04:29
>>784
ベースクラスがテンプレート依存でなければ StringType,IntegerType
は見えるが、そうでない場合は 795 のように書く必要がある。

実はずっと前の GCC で VC7.1 みたくエラーにならない時期が
あったんだが、バージョン上げたらエラーになったんで仕様を
確認したことがあったのを思い出したよ。
799デフォルトの名無しさん:2005/08/06(土) 23:17:54
>>798
2.95あたりは確かそうだったね
800デフォルトの名無しさん:2005/08/07(日) 16:48:53
template<class A>
struct Foo
{
  template<class B>
  struct Bar
  {
  };
};

このBarだけを特殊化するのって、GCCでは

template<>template<>
struct Foo<int>::Bar<int>

って書かなきゃならないんだね。
VC++7.1では

template<>
struct Foo<int>::Bar<int>

で通るんだけど、これはバグなのかな?
801デフォルトの名無しさん:2005/08/07(日) 16:55:26
>>800
どっちが規格に準じてるかによるね
802デフォルトの名無しさん:2005/08/07(日) 17:00:26
>>800
14.7.3.17 より
"If the declaration of an explicit specialization for such a member appears in namespace scope, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized."

template<> template<> ... と繰り返すのが正解っぽい。
803デフォルトの名無しさん:2005/08/07(日) 17:10:09
>>800
gccを信じてそちらに合わせておけ。
804デフォルトの名無しさん:2005/08/07(日) 17:27:08
>>800
gccのバージョンは何?
g++ 3.3.5
だとそれ両方とも通るんだけど
新しいのは通らないのかな?
805デフォルトの名無しさん:2005/08/07(日) 18:19:07
template <class T>
typename enable_if<boost::is_integral<T>, void>::type
foo(T t) {}
で関数を定義したりできないのはわかるけど
これでclassのコンストラクターを定義したりしなかったりを決めると

コンストラクターに戻り値が定義されています

と怒られる。何か方法ないのでしょうか?
template <class T>
class A{
typename enable_if<boost::is_integral<T>, void>::type
A(T t) { }
}
806デフォルトの名無しさん:2005/08/07(日) 18:44:57
>>805
SFINAEは戻り値の型でやる方法と(デフォルト)引数の型でやる方法の2通りできて,
コンストラクタの場合は戻り値の型を指定できないですから引数の型のほうでやります.

template<class T>
class T{
A(T t, typename enable_if<boost::is_integral<T> >::type * = 0){}
};

こんな感じで.逆に演算子関数の場合は余計なデフォルト引数を指定できないので
戻り値型で,という感じになると思います.
807デフォルトの名無しさん:2005/08/07(日) 22:38:01
enable_ifが何をするもんなのか、未だにわかんねえ。
てか、何年英語の勉強してもboostのドキュメントさえ読めない俺ってすげえよ。
よっぽど英語の才能が無いんだな。
808デフォルトの名無しさん:2005/08/07(日) 22:41:04
テメェは自己紹介がしたいだけだろ
分からねぇんだったらイチイチ出てくんな
809デフォルトの名無しさん:2005/08/07(日) 22:50:40
>>807
SFINAEによるオーバーロードセットのコントロールを簡単に
行うためのユーティリティ。

英語分からなくてもC++分かるんならひたすらソース詠めば
何となく見えてくる、かもよ。
810デフォルトの名無しさん:2005/08/07(日) 22:53:46
>>808
なにキレてんのキミ。
相手以上の駄レス書いてたら意味無いのに。
811デフォルトの名無しさん:2005/08/07(日) 22:59:07
駄レスとかいってたら、ほとんどがそうだろw
812デフォルトの名無しさん:2005/08/07(日) 23:00:10
ほとんどがそうならなおのこと
突然特定のレスにキレる理由が無いよ。
813デフォルトの名無しさん:2005/08/07(日) 23:03:27
自己顕示欲丸出しの厨房がウザイだけだろ
まあ、どこにでもいるからいちいちキレるのもどうかと思うが
814デフォルトの名無しさん:2005/08/07(日) 23:16:33
キレて説教するほうがよっぽど自己顕示欲激しいと思う。
世に言う自爆ですな。アホくさ。
815デフォルトの名無しさん:2005/08/07(日) 23:17:52
http://www.boost.org/libs/utility/enable_if.html
ここの「1.2 Background」は、何が問題だって言ってるんですか?
816デフォルトの名無しさん:2005/08/07(日) 23:20:01
説教がどう自己顕示欲につながるんだ??
817デフォルトの名無しさん:2005/08/07(日) 23:22:14
>>814
ワロス
818デフォルトの名無しさん:2005/08/07(日) 23:29:27
>>816
キレるたびにいちいちスレ違いの書き込みするような奴が
自己顕示欲薄いって言い張る気?
819デフォルトの名無しさん:2005/08/07(日) 23:30:34
enable_ifがわからんってののどこが自己顕示欲に繋がるのかもわからんけどな
820デフォルトの名無しさん:2005/08/07(日) 23:30:49
>>818
藻前もキレてるじゃん
あと煽り耐性なさ過ぎ
いい加減スルーしろよ
821デフォルトの名無しさん:2005/08/07(日) 23:31:47
>>815
いや,そこの部分は別に何かが問題だなんて書いてないです.
単にSFINAEというのがどう機能するか(そしてなぜそのような機能が必要なのか)
を説明しているだけです.
822デフォルトの名無しさん:2005/08/07(日) 23:32:15
816が煽りには見えないけどなあ。
普通にズレてるだけで。
823デフォルトの名無しさん:2005/08/07(日) 23:32:55
>>815
あっと,「もしSFINAEがなければこういうことが問題だよね」というのは書いてますけれど.
824デフォルトの名無しさん:2005/08/07(日) 23:35:03
>>822
分かったからもう出てくんな
825デフォルトの名無しさん:2005/08/07(日) 23:40:11
本日の推奨NG
「。」「顕示」「煽り」「キレ」
すっきりして(・∀・)イイ!!
826デフォルトの名無しさん:2005/08/08(月) 02:07:36
expressional template
VC.net2003だと、ちょっと複雑な式を書いただけで
コンパイル通らない。
そういうものなの?
gccなら通るのかな
827デフォルトの名無しさん:2005/08/08(月) 02:12:44
>>826 その「ちょっと複雑な式」とやらを晒すとレスが付くかもしれない。
828デフォルトの名無しさん:2005/08/08(月) 03:35:21
>>826
現存する如何なるコンパイラでも通らない程複雑(広義の)なコードに問題ありに100円。
829デフォルトの名無しさん:2005/08/08(月) 04:40:19
ネストが17超えるとか?
830デフォルトの名無しさん:2005/08/08(月) 15:16:31
いろんな要素が混じってるので必ずしもexpressional templateが
原因でないのかもしれないけど

boost::numeric::ublas::matrix & A(){return A_ }
boost::numeric::ublas::matrix & B(){return B_ }

B() = prod( A(), A())*3 + B() + ....

こんな感じかな.全部はさらせないのですまそ
831デフォルトの名無しさん:2005/08/09(火) 01:41:27
>>830
エラー貼ったがいいよ
もし膨大なら
再現するコンパイル可能な最小のコードを貼って
832831:2005/08/09(火) 01:45:25
>コンパイル可能な
おっとコンパイルは通らないのか

>あなたがコンパイル通らないことを理不尽に思う
に訂正

ようするにテストする側の身になってコードを
貼ってください
833デフォルトの名無しさん:2005/08/09(火) 11:45:51
>>830
>こんな感じかな.全部はさらせないのですまそ

じゃあ、他の人にエラーの原因を調べてもらうのも諦める事ですな。
証拠不十分なまま、証言台に立つような物ですぞ。
834デフォルトの名無しさん:2005/08/20(土) 08:39:28
だれもいない
835デフォルトの名無しさん:2005/08/20(土) 20:28:20
ホントにだれもいないのかよ
836デフォルトの名無しさん:2005/08/20(土) 20:39:26
いねーよ
837デフォルトの名無しさん:2005/08/20(土) 20:40:28
質問やら話題があれば人は自然と集まってくる。
838デフォルトの名無しさん:2005/08/20(土) 20:52:57
おまえら
”てんぷれーと”にだまされてないか?
”しーぷらぷらのてんぷれーと”って結局あれだよ。
中途半端。
そう中途半端。
LISPに比べたら。
全然読み易くならない。
いろんな括弧であふれてLISPの方がまだサルのように読みやすい。
まあここにタムロしてるおまえらの言い分は判ってるよ
こうだろ、静的カタカタ型が重要なんです!
LISPじゃすぴーどでないよプププ
とかな。
ばーか。
カタなんかより柔軟性なんだよこのご時世はよ
カタカタうるせーのなんのって、笑うわ。
C++考えた奴みたいにハゲろ
全員
839デフォルトの名無しさん:2005/08/20(土) 20:59:39
確かに、「ネイティブコード吐く言語じゃないと速度が」
とか必死に言ってる奴に優秀なプログラマはいないな。
840デフォルトの名無しさん:2005/08/20(土) 21:10:42
しーぷらぷらの処理系。
てんぷれーとバグだらけ。
笑うわ。
いったい何年てんぷれーとやってんだよ
おまえらがべんだーの修正待つあいだに
おれLISPで新しいマクロどっさり作る
生産性バカたけぇーわLISPはよ
LISPはカタないからすぴーどでないよプププて、
そりゃ頭がかてえ証拠だな。
そんな奴は引退したほーがいいんじゃねーかなあ
LISPにカタないなら組み込めよ、ハゲども
ぶーとすとらっぷとか考えろよ
わかるか?ぶーとすとらっぷって。
しーぷらぷらにはそんながいねんはないかもなあ。
最適化なんかやりやすいなーすいすいいけるぜ
こんすの海の中にいると不満なんてすぐ解消する
それがLISP。
まあ頭のかたいカタカタ野郎は
やっぱりC++考えた奴みたいにハゲろ
全員
841デフォルトの名無しさん:2005/08/20(土) 21:16:51
>>839よりは優秀だけどね。
842マイク ◆yrBrqfF1Ew :2005/08/20(土) 21:31:32
C++をしーぷらぷらなんて言うのは無能。
843デフォルトの名無しさん:2005/08/20(土) 21:59:52
C++でLisp系の俺言語&処理系作るのが最近の俺の趣味なんだが、
なんかこいつの仲間と思われたくないな、恥ずかしくて。
844デフォルトの名無しさん:2005/08/20(土) 22:59:08
>>842
シープラスプラス?
それともシーたすたす?
845デフォルトの名無しさん:2005/08/20(土) 23:33:28
しーいんくりめんと
846デフォルトの名無しさん:2005/08/20(土) 23:43:58
C++
後置ということは、まだ本当のC++にはであてないわけだ
847デフォルトの名無しさん:2005/08/20(土) 23:45:24
C++には出会えている
++Cに出会えてないだけ
848デフォルトの名無しさん:2005/08/21(日) 00:37:45
838は、C++のテンプレートが読みにくく、
コンパイラのバグのことも分かっていて、
C++作った人物についても詳しいようだな
849デフォルトの名無しさん:2005/08/21(日) 00:48:03
Schemeの純粋指向にはあこがれるけど、Lispはどうでもいいや。
継続は面白いな。

>LISPはカタないからすぴーどでないよプププて、
型が無いと遅くなるつうのは初耳ですが、どこの情報?
850デフォルトの名無しさん:2005/08/21(日) 01:06:13
>>849
VBのバリアント型みたくデータ側に型情報があるから
オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。
型判定に値の取り出しとか最低でもCの3倍以上のコストが掛かる。
Rubyが遅いのもこれがかなり影響してる。
851デフォルトの名無しさん:2005/08/21(日) 01:09:17
でも日本語は不自由なようだ。
852851:2005/08/21(日) 01:09:45
853デフォルトの名無しさん:2005/08/21(日) 01:25:23
> オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。
随分ダサい実装ですね。
854デフォルトの名無しさん:2005/08/21(日) 01:41:07
そのダサイ実装を越えたところに桃源郷が
855デフォルトの名無しさん:2005/08/21(日) 01:41:43
ももげんごう?
856デフォルトの名無しさん:2005/08/21(日) 12:12:15
ももげんごう(←なか変換できない)
857デフォルトの名無しさん:2005/08/21(日) 14:42:55
桃源郷=Xanadu キサナドゥ
858デフォルトの名無しさん:2005/08/22(月) 00:38:44
>>850
正直、有名なコンパイラならそんなださい実装は少ないよ。
Common Lispには型指定の構文があるくらいだし。
859デフォルトの名無しさん:2005/08/23(火) 09:18:30
数値計算したい人は
速度気にしないならlistでなくてMatlab使う
860デフォルトの名無しさん:2005/08/23(火) 15:06:35
>>858
CLOS基地外氏ね
スレ違いだし
861デフォルトの名無しさん:2005/08/23(火) 15:34:43
だれもいないからとか言うから
862デフォルトの名無しさん:2005/08/23(火) 16:29:46
人稲杉なので、チラシの裏

boost::bind は、bind( f, _1, _2, a, b, _1 ) を行うことで、
func::return_type ( A1 & a1, A2 & a2 ) というファンクタを返すけど、
この _1 や _2 を、_decimal や、_text、_float のような書式指定プレイスホルダに
置き換えて、以下のようにすれば、タイプセーフな printf が出来るなと
考えたことがあった。

function< void( int ) > f = format( cout, "a = ", _hex, endl );
// ↑ cout << "a=" << %x << endl; と同じ事を行うファンクタを返す。
f( 10 ); // cout << "a=" << hex << 10 << endl;
f("aaa"); // コンパイルエラー

上の形とは違うけどその思想に基づいて実際に作ってみたことがある。
でも結局実用では (w)sprintf しか使わなかった。勉強にはなったけどね。
template プログラミングは楽しいけど、冷静なるとしなくていいことまで
テンプレート化してたりしていることがあるので気をつけないと。
863デフォルトの名無しさん:2005/08/23(火) 17:12:40
>>862
> 冷静なるとしなくていいことまでテンプレート化してたりしていることがある
昨夜、そんな関数テンプレートを必死で非テンプレート関数に直してた・・・。
数日前に必死で関数テンプレートにした箇所だったのだけど・・・。
864デフォルトの名無しさん:2005/08/24(水) 12:24:27
template<typename X_TYPE>
void xxx(X_TYPE x)
{}
として型の自動認識の手間減らしは多用するな
865デフォルトの名無しさん:2005/08/24(水) 13:32:40
そうね。時々やる。いっそのこと型を書くのはオプションにして
MLみたいに型推論してくれればいいのにと思う。
866デフォルトの名無しさん:2005/08/24(水) 17:50:00
C++ 0xだとそんな機能が追加されるとかされないとか。
867デフォルトの名無しさん:2005/08/28(日) 09:36:27

テンプレートがちんぷんかんぷんでまったく理解できない私に
理解できるようになる方法を教えてください。まじで。
868デフォルトの名無しさん:2005/08/28(日) 11:02:49
引数の型を使うときに決められるんだよ。
869デフォルトの名無しさん:2005/08/28(日) 11:35:27
>>867
騙されたと思ってstd::min()でも使って味噌。
870デフォルトの名無しさん:2005/08/28(日) 13:22:51
せめてstd::vector くらい使わないとありがたみ沸かないだろう。
871デフォルトの名無しさん:2005/08/28(日) 18:04:02
>>867
つ[C++ Templates(英文)]
872デフォルトの名無しさん:2005/08/29(月) 06:58:30
STL バンザイ
873デフォルトの名無しさん:2005/08/29(月) 21:56:02
STLとboostが無かったら俺C++使いつづけて無かったよ。
874デフォルトの名無しさん:2005/08/29(月) 22:30:29
俺もそうだ。
875デフォルトの名無しさん:2005/09/03(土) 00:21:09
会社でtemplate使うなって言われたんだけど…
何故?
876デフォルトの名無しさん:2005/09/03(土) 00:24:13
会社で使いこなせるヤシがいないからと邪推
877デフォルトの名無しさん:2005/09/03(土) 00:31:06
代わりにLISP使え

もっと困るかもな
へへ
878デフォルトの名無しさん:2005/09/03(土) 03:19:35
>>875
それは、あなたが馬鹿だからです。
879デフォルトの名無しさん:2005/09/03(土) 03:26:37
お前だけは使うなって言われたなら
そうかもしれないけどさ
880デフォルトの名無しさん:2005/09/03(土) 09:13:41
>>875
まともな会社にうつるべし
881デフォルトの名無しさん:2005/09/03(土) 09:55:32
>>875
会社に聞け。
ここで聞くようなやつは>>878に決定。
882デフォルトの名無しさん:2005/09/03(土) 10:02:04
>>881
なんでそんな必死にこの話題にフタしたがるの?
コンプレックスでも刺激された?w
883デフォルトの名無しさん:2005/09/03(土) 11:09:31
>>882
頭、大丈夫か?
884デフォルトの名無しさん:2005/09/03(土) 14:45:37
VC6のプログラム保守してるとかじゃないのか>875
885デフォルトの名無しさん:2005/09/03(土) 22:33:39
>>883
大丈夫だよ。
質問に答えられない誰かさんの頭は大丈夫じゃないみたいだけど。
886デフォルトの名無しさん:2005/09/04(日) 03:17:12
・移植性重視
・扱える開発者が少ない or メンテする人が固定とは限らない

のどっちかだろうねえ
後者の事情のほうが多いと思うけども
887デフォルトの名無しさん:2005/09/09(金) 02:16:23
管理職の団塊世代が、ピュアなC以外理解できないとか
888デフォルトの名無しさん:2005/09/09(金) 22:28:28
名前空間→記述が冗長すぎる
テンプレート→制限が多すぎる
クラス→継承が可読性を悪化させる
その他→コンパイル時間が長すぎる
889デフォルトの名無しさん:2005/09/09(金) 23:39:18
C++→俺が解からない
890デフォルトの名無しさん:2005/09/09(金) 23:45:15
俺が解からない→みんなも解からない
891デフォルトの名無しさん:2005/09/10(土) 02:04:02
>>886
>移植性重視

templateって移植性下がるの?
892デフォルトの名無しさん:2005/09/10(土) 02:33:11
例えばGCCと心中するつもりならGCCで動けばOKって人もいるでしょ
893デフォルトの名無しさん:2005/09/10(土) 02:46:27
>>891
ある程度ISO C++に準拠したコンパイラがない環境には移植できなったりだとか。
894デフォルトの名無しさん:2005/09/10(土) 03:16:30
少なくとも、vc7.1とgccの両方で動くテンプレートくらい書けないと
話にならないと思うけど。
895デフォルトの名無しさん:2005/09/10(土) 12:53:08
VC7.1とgcc3.3以降で動くテンプレート書くのは簡単だろ、どっちもほぼ100%標準準拠なんだから。
むしろVC6とかgcc3.2とかで動くか動かないか判断する方が難しいと思われ。
896デフォルトの名無しさん:2005/09/10(土) 13:14:28
>>895
VC6とgcc3.2以前はもうあきらめた。
というかエラーメッセージすらとんちんかんな時があるのが頭痛い。

昔の仕事のプロジェクトコードのメンテでちょっとしたテンプレート書いてとかで
引っかかると泣きたくなる。
897デフォルトの名無しさん:2005/09/10(土) 13:25:22
>>894-895
まるで、複数コンパイラで有効なテンプレートを書くのが上級者であるかのような言い方だな。
そういった汎用性のあるテンプレートは入門者レベルの機能しか使ってない。
君らは、入門者レベルのテンプレートしか書いたことないんだろ?
898デフォルトの名無しさん:2005/09/10(土) 13:31:55
スレの存在を否定するような行為が、目下のベストな対処法

「技巧に走らない」
899デフォルトの名無しさん:2005/09/10(土) 14:04:38
>>897
> であるかのような言い方だな。
印象だけでものを書く場合、その印象がトンチンカンだと
残りの文章がすべてトンチンカンになるから今後は気をつけな。
900デフォルトの名無しさん:2005/09/10(土) 14:25:57
シンプル伊豆ベスト
901デフォルトの名無しさん:2005/09/10(土) 15:15:35
>>897
「入門者レベル」とか「汎用性のある」とか、
自分が「上級者」じゃない事がバレバレなんですがw

まぁ、恥の上塗りだけはしないようになw
902名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:43:40
>>888
つまり、templateに限らずC++は糞だって事で包茎?
903名無しさん@そうだ選挙に行こう:2005/09/10(土) 19:37:56
ていうかお前が包茎。
904名無しさん@そうだ選挙に行こう:2005/09/10(土) 19:45:33
24時間テレビ C++ は地球を救う
905名無しさん@そうだ選挙に行こう:2005/09/10(土) 20:09:37
>>902,904
んなこたーない。
906名無しさん@そうだ選挙に行こう:2005/09/10(土) 22:11:14
>>894は馬鹿だな。
907名無しさん@そうだ選挙に行こう:2005/09/11(日) 01:31:57
894は、VC以外でも通るように、typenameちゃんと書けとか
その程度の意味じゃねえの?
908名無しさん@そうだ選挙に行こう:2005/09/11(日) 05:40:17
言語仕様が複雑すぎて処理系が追いつかないのは本末転倒

言語仕様満たしてから最適化とかやれよ馬鹿ベンダーはよ
現実逃避してんじゃねーよ
909名無しさん@そうだ選挙に行こう:2005/09/11(日) 07:05:25
ヒント:需要と供給
910名無しさん@そうだ選挙に行こう:2005/09/11(日) 09:16:30
つまりDelphiが最強ということになるな。
911名無しさん@そうだ選挙に行こう:2005/09/11(日) 09:37:08
Delphi知らないんだけどtemplateみたいなのあるの?
912名無しさん@そうだ選挙に行こう:2005/09/11(日) 09:44:31
あるか!
913名無しさん@そうだ選挙に行こう:2005/09/11(日) 09:52:58
なぜ怒る・・・。
そこがDelphi信者のコンプレックスなのか?
914名無しさん@そうだ選挙に行こう:2005/09/11(日) 09:57:55
でもDelphiってすごいよね
一代でここまでメジャーになった言語パッケージってないでしょ
それともPascalの下積みがあったから?
915名無しさん@そうだ選挙に行こう:2005/09/11(日) 10:18:13
>>914
世間ではC#の方がメジャーだと思うがね。
916名無しさん@そうだ選挙に行こう:2005/09/11(日) 10:20:04
C#は単なるM$の宣伝力だと思うけど
917名無しさん@そうだ選挙に行こう:2005/09/11(日) 11:13:26
>>916
CとかC++から名前の連続性もあるしね。
918名無しさん@そうだ選挙に行こう:2005/09/11(日) 12:07:50
C#なんて使って製品開発とかしてる香具師っているの?
919名無しさん@そうだ選挙に行こう:2005/09/11(日) 14:40:54
天下のM$がVBで真似したぐらいだからな
当時はRADは斬新な開発環境だった
920名無しさん@そうだ選挙に行こう:2005/09/11(日) 15:18:44
Delphi使いこそプログラマの頂点ということか。
921名無しさん@そうだ選挙に行こう:2005/09/11(日) 16:34:19
Delphiが当初からMS謹製であったならば、VBだ、MFCだ、ATLだ、WTLだ、
STLだ、.Netだ、C#だ、C++/CLIだといったことで右往左往することもなく
10年間一貫とした言語体制、RAD環境、爆速コンパイル、コンポーネント化
による高い生産性等々を皆が維持・共有できたかと思うと残念でならないよ。
922名無しさん@そうだ選挙に行こう:2005/09/11(日) 16:49:55
C#って、Delphi作った香具師が理想の言語として設計したんだろ。

Delphi信者御苦労様w
923名無しさん@そうだ選挙に行こう:2005/09/11(日) 18:34:04
まだDel厨いたのか
そろそろ博物館に行けよ
924名無しさん@そうだ選挙に行こう:2005/09/11(日) 20:14:45
博物館の恐竜が一緒に浮かれて踊ったぜ
925名無しさん@そうだ選挙に行こう:2005/09/11(日) 23:35:20
>>921
STLだけその中で異質だな。
926デフォルトの名無しさん:2005/09/12(月) 09:47:06
予想通り嫌Del厨が暴れることになったか・・・
927デフォルトの名無しさん:2005/09/12(月) 11:54:51
つか、スレ違いうぜぇですよ?
928デフォルトの名無しさん:2005/09/12(月) 11:58:56
>>924
子門乙
929デフォルトの名無しさん:2005/09/14(水) 15:45:52
template< typename char_type, tepename char_traits >
std::basic_ostream< char_type, char_traits >& operator<< ( std::basic_ostream< char_type, char_traits >& stream, const int& value )
{
stream << "value = " << value << endl;
return stream;
}

この関数内で文字列リテラル"value = "を
char_type がcharなら、"value = "
char_type がwcharなら、L"value = "
にしたいんですが、どうしたら良いでしょうか?
930デフォルトの名無しさん:2005/09/14(水) 16:12:57
>>929
テンプレートの特殊化か、オーバーライドで解決させる。

ex)
inline char const * choice( char const * s, wchar_t const *, char )
{
 return s;
}
inline wchar_t const * choice( char const *, wchar_t const * s, wchar_t )
{
 return s;
}

stream << choice("value=",L"value=",char_type()) << value << endl;
931929:2005/09/14(水) 16:31:48
>>930
#define literal_str( char_type, str ) choice( str, L##str, char_type##() )
付きで採用しますた。
ありがとうございました。
932デフォルトの名無しさん:2005/09/14(水) 17:21:04
>>931
二番目の##は余計。
933929:2005/09/14(水) 21:31:05
だからなんだよこのタコ助!
934デフォルトの名無しさん:2005/09/14(水) 22:41:20
確かに余計だな。
935929:2005/09/15(木) 00:04:09
>>933
>>929の著作権は私にあります。
なんなら出るとこ出ても・・
と思いましたがきっと>>933
私にインスパイヤされて誕生した新種なんでしょう。
今回はかんべんしてやります。
936デフォルトの名無しさん:2005/09/15(木) 11:53:02
template <class T>
void f1(T t)
{
 f2(t);
}

void f2(int) {}

int main()
{
 f1(1);
}

というコードは正しいのでしょうか?

VC7.1 ではコンパイル可能で comeau ではコンパイルできません。
937デフォルトの名無しさん:2005/09/15(木) 12:50:56
>>936
comeauだとなんてエラーが出るの?
938636:2005/09/15(木) 13:09:16
>>637
identifier "f2" is undefined
detected during instantiation of "void f1(T) [with T=int]"

というエラーです。strict mode のみのようです。

ちなみに、ユーザ定義型の場合は期待通りにコンパイルできました。

template <class T>
void f1(T t)
{
 f2(t);
}

struct a{};
void f2(a) {}

namespace adl
{
 struct a{};
 void f2(a) {}
}

int main()
{
 f1(a());
 f1(adl::a());
}

このコードはコンパイル成功。
939デフォルトの名無しさん:2005/09/15(木) 14:23:18
>>936
gcc3.4.4(MinGW) で、-Wallで通る。
940デフォルトの名無しさん:2005/09/15(木) 14:26:00
>>938
プロトタイプ宣言したら?
941デフォルトの名無しさん:2005/09/15(木) 14:31:54
>>938
f2()のプロトタイプ宣言が必要っぽい。
942デフォルトの名無しさん:2005/09/15(木) 16:28:36
Incompatibilities Between ISO C and ISO C++, David R. Tribble

http://david.tribble.com/text/cdiffs.htm#C90-impl-func
・ Implicit function declarations

> C++ does not allow implicit function declarations. It is invalid to call a function
> that does not have a previous declaration in scope.
>
> C99 no longer allows functions to be implicitly declared.
> The code above is invalid in both C99 and C++.
943デフォルトの名無しさん:2005/09/15(木) 17:47:26
>>936
標準の (14.6.4.2/1) をそのまま読む限りでは, unqualified name lookup として
解決される名前は point of definition の文脈のみが考慮されて,
associated namespaces を用いた名前解決(要するにADL)では,point of definitionと
point of instantiation の双方の文脈が考慮されるみたいですね.なので,

>>936 の f1(1) という呼び出しにおける f1 中の f2(t) に対する名前解決の場合,
unqualified name lookup では f2 の呼び出しを定義している場所(point of definition)
からは f2 という名前は解決されないので失敗し,さらに f2(t) は int を引数とした
呼び出しのために associated sets of namespaces and classes も空 (3.4.2/2) の
ため,ADL 経由でも f2 は見つからずに,結果 f2(t) という関数呼び出しに対応する
名前の解決が失敗する.

一方で,>>938 の f1(a()) 及び f1(adl::a()) という呼び出しにおける f1 中の f2(t)
に対する名前解決の場合,>>936 と同様 unqualified name lookup による名前解決は
失敗する.ところが,a 及び adl::a はユーザ定義型で,各々グローバルと adl が
associated namespace になる.この場合,f2(t) という呼び出しが定義されている
場所 (point of definition) と f1 がインスタンス化された場所
(point of instantiation) 双方の文脈が名前解決において考慮される.結果,
point of instantiation の文脈で void f2(a) と void adl::f2(adl::a) が
visible のため,これらの名前解決が成功する.

と,こういう感じだと思います.ちなみに VC++7.1 の挙動は,dependent name だろうが
non-dependent name だろうが,ADL 経由だろうがなかろうが,全て
point of instantiation の文脈も考慮するという実装になっているための結果で,
これは標準に準拠した挙動ではないです.
944943:2005/09/15(木) 17:49:27
あ,すいません.長々と書きましたけれど結論としては,
936のコードは(標準に準拠していないという意味で)正しくないと思います.
945936:2005/09/15(木) 22:07:49
>>943
なるほど。
実体化の時点で名前の解決を行っても、
実体化の時点の文脈が考慮されるとは限らないんですね。

皆様、ありがとうございました。
946デフォルトの名無しさん:2005/09/15(木) 22:41:25
template<class T>
class Foo {
 public:
    ...;
 private:
    class Bar { 
    public:
        ...;
        bool operator()(const Bar& l, const Bar&r) const;
    private:
        T m_value; 
        int misc_info;
    };
    
    std::multiset<Bar, Bar::Comp> m_bars;
};

m_bars の先頭・末尾に番人(misc_value などは他のメ
ンバと同様にアクセス可能にしたもの)を導入したいの
ですが、どういうアプローチで作れば良いでしょうか?
947デフォルトの名無しさん:2005/09/16(金) 01:33:46
>>946 undeclared identifier `misc_value'
948デフォルトの名無しさん:2005/09/16(金) 09:43:59
>>946
テンプレート関係ないやん。
949デフォルトの名無しさん:2005/09/18(日) 16:56:08
STLportではコンパイルできるけれど、
g++のSTLではエラーが出てしまうようなコードってどんなものがあるでしょうか?
vectorやstringくらいしか使ってないんですが、コンパイルでエラーが出ます。。
950デフォルトの名無しさん:2005/09/18(日) 17:25:59
エラーメッセージ書かん奴には答えない
951デフォルトの名無しさん:2005/09/18(日) 17:33:35
>>949
氏ね!
952デフォルトの名無しさん:2005/10/05(水) 16:55:29
template<int num, int count> struct power{ enum { value = power<num, count-1>::value * num }; };
template<int num> struct power<num, 1>{ enum { value = num }; };
template<int num> struct power<num, 0>{ enum { value = 0 }; };
template<> struct power<0, 0>{ enum { value = 0 }; };
       ∋oノハヽo∈
         ( ´D`) <テンプレート ♪ で、計算♪計算♪  age♪ age♪
          (つ┳9
         (_)┃_)
          ━§━
            §
   ⌒ヽ〃⌒ヽ〃    
int main()
{ //2の8乗
cout << power<2, 8>::value << endl;
return 0;
}
953デフォルトの名無しさん:2005/10/05(水) 18:45:40
>template<int num> struct power<num, 0>{ enum { value = 0 }; };

それはどうかと思うぞ。
954デフォルトの名無しさん:2005/10/05(水) 19:02:12
template<int num> struct power<num, 0>{ enum { value = 1 };};
955デフォルトの名無しさん:2005/10/05(水) 19:13:50
<0,0>,<num,1>の特殊化は必要ないな
956デフォルトの名無しさん:2005/10/05(水) 21:12:57
むしろこうしてコンパイル時エラーにしろよ。
template<> struct power<0, 0>{};
957デフォルトの名無しさん:2005/10/05(水) 21:24:22
0^0って数学的にはどうなるの?
958ヽ(´ー`)ノ ◆.ogCuANUcE :2005/10/05(水) 22:22:38
>>956
n^0 = 1
959ヽ(´ー`)ノ ◆.ogCuANUcE :2005/10/05(水) 22:23:20
スマン。レス番間違えた orz
960デフォルトの名無しさん:2005/10/05(水) 22:28:09
>>957-958
一方で0 ^ n = 0となっているから問題になる。
ところで^と言えばXORの立場が。
961デフォルトの名無しさん:2005/10/06(木) 12:22:20
VC6のtemplate関数ってバグある気がするんだけど...
template<typename T> void test();
引数無し呼んだときに解決できてないみたい...
template<typename T> void test(const T&);
みたいにすればオーバーロードで解決できるのか、大丈夫みたいなんだが...
962デフォルトの名無しさん:2005/10/06(木) 12:36:11
いまどきそんな化石コンパイラに文句言われても…
963デフォルトの名無しさん:2005/10/06(木) 13:39:14
化石以前にtemplateに関しては欠陥コンパイラですから・・・
964デフォルトの名無しさん:2005/10/06(木) 17:42:46
そもそもC++コンパイラじゃないですから
965デフォルトの名無しさん:2005/10/06(木) 22:25:31
少なくともANSI/ISO C++準拠とは言えないな。
966デフォルトの名無しさん:2005/10/07(金) 04:44:36
じゃーVC7はどうですか?
967デフォルトの名無しさん:2005/10/07(金) 05:23:27
7.1はかなりまとも。
968デフォルトの名無しさん:2005/10/07(金) 12:23:52
7と7.1は全然違うぞ
7はかなり微妙
969デフォルトの名無しさん:2005/10/07(金) 13:11:10
7はCStringにバグがあったね。STL周りもちょっと不安定なところがあった気もする。
970デフォルトの名無しさん:2005/10/07(金) 14:50:27
7.1って具体的にclのどのバージョン?


Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
っての使ってるけど
971デフォルトの名無しさん:2005/10/07(金) 15:06:35
VS.net(VC.net)2003か、VCTK2003のやつが7.1
13.10.3077なら7.1だな。VS.net2003の方のやつだろ。
972デフォルトの名無しさん:2005/10/14(金) 17:36:27
codeguruに記事の投稿してみたがレビュー通んないとだめなんだね
973デフォルトの名無しさん:2005/10/18(火) 15:57:25
age
974デフォルトの名無しさん:2005/10/26(水) 22:29:10
人稲杉なので、バカネタを投下。
http://www.hakusi.com/up/src/up5538.zip.html

Boost.Lambda みたいに Expression Template を使った、引数に対して安全なフォーマットライブラリ。
Boost.Function や、Boost.Bind と組み合わせることが可能。
以前作成したものと違い、オマケ機能だが入力も可能で、ワイド文字にも対応。

ただ、 _ と % だらけで見た目がキモイ上に、実用性がイマイチ謎。
Expression Template の資料として。

// 出力
 string strA, strB;
 sprint( strA, "1 " % !_x[6] % "/" % _s, 10, "aaaa" ); // sprintf( str, "%#6x/%s", 10, "aaaa" ); みたいな。
 sprint( strB, "2 " % (!_x[6]*='0') % "/" %_s, 10, "aaaa" ); // sprintf( str, "%#06x", 10, "aaaa" ); みたいな。
 cout << strA << endl; // 1 0xa/aaaa と出力
 cout << strB << endl; // 2 0x000a/aaaa と出力
// 入力
 int xA, xB;
 string yA, yB;
 sscan( strA, "1 " % _ws % _x % "/" % _s, xA, yA ); // 空白部分はスキップさせる
 sscan( strB, "2 " % _x % "/" % _s[3], xB, yB ); // 文字列部分は3文字のみ取得
 // 出力
 print( cout, "xA = " % _d % "\nyA = " % _s % _endl, xA, yA );
 print( cout, "xB = " % _d % "\nyB = " % _s % _endl, xB, yB );
 // xA = 10
 // yA = aaaa
 // xB = 10
 // yB = aaa と出力
975デフォルトの名無しさん:2005/10/27(木) 00:15:14
>>974
せっかくなので便乗しておきますね.将来の話なのでアレですけれど.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1603.pdf
976デフォルトの名無しさん:2005/10/29(土) 10:05:49
難読コンテスト会場はここですか?
977デフォルトの名無しさん:2005/10/31(月) 13:08:43
>>974
すげー--w
確かに scanf っぽいこと出来るし。

でも、Perl みたいで汚いな。使おうとは思わんけど。
978デフォルトの名無しさん:2005/10/31(月) 13:59:50
>>974
マジキモス
979デフォルトの名無しさん:2005/11/02(水) 14:02:41
>>974
良くこんなん書く気になるなあ。
980デフォルトの名無しさん:2005/11/02(水) 14:40:35
>>975
boostな人達はあれば便利だけど、一般人的にはどうなのかなあ?
981デフォルトの名無しさん
>>980
どの辺が便利なのか理解に苦しむ。