【C++】template 統合 ..
[2ch|▼Menu]
75:73
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を使っていくべきじゃなかろうか

83:Addicted 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
>>90
URLリンク(www.tietew.jp)

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
>>96 (´゚c_,゚` ) プッ
URLリンク(www.google.co.jp)

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
使ってすぐ分かるのは、コンテナから取り出すときにナローイング変換しなくていいこと。

123:120
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のこと嫌いなの?

151:135
04/12/28 18:54:45

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

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

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

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

皆様ありがとうございました。

152:151
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の機能のキの字も使ってないもんなぁ。

166:161
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
そんな感じでいいんじゃないの?

170:168
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; \

長いので詳細は↓に書いてあります。
URLリンク(www2.odn.ne.jp)

割と使えると思うんだがどうだろう?


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();
};


183:181
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が評価される前に$が評価されてしまうので結局同じことになりませんか?

色々漁ってみたら限界はあるもののいくつか対処法はあるみたいですね.
URLリンク(lists.boost.org)からだと

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か
どうかでマクロを使い分ける必要もありますね,これ.
・・・っていうか話題をそらしてしまってすいませんです.

185:181
05/01/07 00:10:36
>>184
コンパイル通らないですか?
当方、VC++ 2003 しかないので、他のコンパイラだと通らないのだったら正直すまん
ただ、VC++ 2003 でも多重にマクロを定義している時は、評価順序によって通らない時もある
その時はマクロを調整するでは駄目ですか・・?

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




186:181
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の引数過多

188:184
05/01/07 21:39:12
>186
考えてみた結果enclosing scopeがtemplateかどうかに対する切り分けが
本質的に必要ではないかと思うのでこの方法はあまり使えなさそうです.

>187
マクロのargument substitutionについて理解が足りていませんでした.
function-like macroがidentityされてから後,replacement-listに対する
置換が実行される前にargumentに含まれるmacro tokenが置換されるんですね.
見た感じやはり184の解法が幾分かbetterでしょうか.

189:181
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$,



190:181
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系ライブラリの提案はすでに色々ありますからね.
自分の知っている範囲だと
URLリンク(www.garret.ru)
URLリンク(www.arneadams.com)
あたりでしょうか?後プロパティの実装なら
URLリンク(www.open-std.org)
とか.
ついでに__if_existsに関して,名前がするかどうかというコンパイル時の情報で
プリプロセッサレベルの処理を行えるというのは確かに強力で魅力的なんですが
やはりVC++限定なのがネックでしょうね.
一応クラスのメンバ(型・関数・変数)や非メンバ関数の存在をテストしてその情報を
コンパイル時に取得する技法を標準C++の範囲内で実装することは可能なので,
それでほとんどの部分は代用できると思います.
(というか自分は本質的に__if_existsが必要な状況を思い付けません)

193:181
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
URLリンク(www.google.com)

199:194
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
URLリンク(www-6.ibm.com)
>言語の機能 であるはずのものが、その言語のユーザーを恐れさせるようになったら、何かを変えるべき時なのです。


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())と書くというのに一票。


238:237
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なんか見てるんだろう、って。

247:237
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なのか。


248:237
05/01/11 22:34:15
ああ、そうか、後者の不安は>>240と書くことで払拭されるのか。
スマソ


249:244
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を使いたくないのかが知りたい

252:250
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);
のような関数を作れば、双方文句はなかろう。

256:255
05/01/12 07:50:40
s/Container/Sequence/

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

これをそのままソースに書いてしまうと言うのは、
例えば定数除算をシフトで書いてしまうのと同等の誤りであると思う。

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スレに書き込もうとしたのだけど、主旨に合わないのでこっちに投棄


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5377日前に更新/262 KB
担当:undef