【C++】template 統合スレ -- STL/Boost/Loki, etc.
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG以下のスレッドを統合するスレです。
STLスレッド
Part1 http://pc.2ch.net/tech/kako/1004/10042/1004287394.html
Part2 http://pc3.2ch.net/test/read.cgi/tech/1026793823/
【C++】Boost使い集まれ!
http://pc3.2ch.net/test/read.cgi/tech/1033830935/
Generic Programming with C++ Template
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
関連スレ、その他リンクは >>2-5 あたりに。
0165デフォルトの名無しさん
NGNGないだろう。class を typename にすれば通るけど。
0166デフォルトの名無しさん
NGNG同じもの作らなくて済ませることができそうな気がする。
これって実行時に判定してるのかな?
Tって静的だけどデバッガで見るとswitch文の中は最適化されてないみたいなんです。
template <typename T> struct FFF
{
FFF(T a=0)
{
switch( class_id(T) )
{
case class_id(char):
std::cout << "char" << std::endl;break;
case class_id(short):
std::cout << "short" << std::endl;break;
default:
std::cout << "other" << std::endl;
}
}
};
template <> struct FFF<int>
{
FFF(int a=0)
{
std::cout << "int" << std::endl;
}
};
0167続き
NGNG{
//出力結果
FFF<int> fff1; //int
FFF<char> fff2; //char
FFF<short> fff3; //short
}
0168デフォルトの名無しさん
NGNGVC++.NET と Bcc5.51 と DigitalMarsC++8.31 と
g++3.2 と g++2.95 と Comeau C++4.31 と Intel C++6.0 では通ったが?
通らないコンパイラを教えてくれ。
0169デフォルトの名無しさん
NGNG0170続き
NGNGclass_id(short) ->3 (enum定数)
直接は飛んでないけど、結局同じなんで問題ないか。
(↓最適化なしのものVC)最適化すると変わるんだろうか...。
; 168 : FFF<char> fff2;
mov DWORD PTR -416+[ebp], 1
cmp DWORD PTR -416+[ebp], 1
je SHORT $L23144
cmp DWORD PTR -416+[ebp], 3
je SHORT $L23145
jmp SHORT $L23146
0171デフォルトの名無しさん
NGNGたとえば >>53
0172デフォルトの名無しさん
NGNGひどいことを言うなよ。お前だってアホだったろうが
0173デフォルトの名無しさん
NGNGひどいことを言うなよ。
0174デフォルトの名無しさん
NGNG確か>>164の脳内コンパイルだと通りません。
0175デフォルトの名無しさん
NGNG0176デフォルトの名無しさん
NGNG0178デフォルトの名無しさん
NGNGやめい、って交換しなきゃ第二引数が省略できんだろ。
0179デフォルトの名無しさん
NGNGtemplate<class T, class U>
T hoge( U foo )
{
...
}
hoge<int>("できますが何か?");
0180160
NGNGああ、なるほど。混乱させてすまなんだ。
U を使うのって Undeducible か何かの略かと思ってたんで>>144と
同じに返値U、引数T、になるようにtemplateの方を変えたんだけど、
Tの次はUってことか。自分では2引数以上のtemplateを書くときは
T1、T2、 T3 ... なのでなぁ。
0181デフォルトの名無しさん
NGNGコロンブス的な発想にチトワラタ(w
0182デフォルトの名無しさん
NGNGtemplate<class T, class U>
を
template<typename T, typename U>
とは書かないの?
0183160
NGNG個人的には、
・タイプ数減らしたい時はclass。
・template template parameter は class と書くので、
何となく全部 class で統一したい気分の日は class。
・マジメに書くときはtypename。
0184デフォルトの名無しさん
NGNGテンプレート引数はclassのみ使用。
typenameは
typedef typename T::iterator iterator;
とがぐらいしか使わない。
0185デフォルトの名無しさん
NGNG漏れはtypenameに直した。
ってか,intとかにも対応するのにclassって気持ち悪いんだよな。C++のintはクラスじゃないし。
0187デフォルトの名無しさん
NGNGまだChapter 3までしか読んでないけど、なかなか良さげ
0188デフォルトの名無しさん
NGNGどこの出版社?(・∀・)イイ?
0189デフォルトの名無しさん
NGNGAddison-Wesley だが……出たばっかの洋書でふ
0191デフォルトの名無しさん
NGNGありが�d。俺も本屋行って見てくるよ。
0192デフォルトの名無しさん
NGNGAddison-Wesley キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!!
Addison-Wesley、もう大好き♪
分かりやすいし、詳しいし…。
0193デフォルトの名無しさん
NGNG俺は int などのプリミティブ型も引数に取る場合には typename, クラスしか
引数に取らん場合には class にしてる。まー、趣味の問題だね。
0194デフォルトの名無しさん
NGNG0195デフォルトの名無しさん
NGNG日本訳が出るまで最低1年はかかるからなー。
0196デフォルトの名無しさん
NGNG0197デフォルトの名無しさん
NGNGまだ使ってるのか… 御愁傷様です。
0198デフォルトの名無しさん
NGNG全く同一だよ。だからみんなして趣味の問題とか個人的にはとか言ってるわけ。
>>195
出たばっかりの洋書はWebで買った方が良いと思う。
0199デフォルトの名無しさん
NGNGhttp://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport
0201デフォルトの名無しさん
NGNG出ますな。
std::cout << boost::lexical_cast<char*>(std::string("abc def")) << std::endl;
std::cout << boost::lexical_cast<std::string>("abc def") << std::endl;
boost::lexical_castはstd::stringstreamを使って実装しているので、
>>演算子や<<演算子がスペースを区切り文字とみなしてしまう故らしい。
何とかして欲しいですな。
0202デフォルトの名無しさん
NGNGhttp://groups.yahoo.com/group/boost/files/lexical_cast_proposition/
…では直ってるので1.30では修正が取り込まれると思いたい。
と言いながら結局1.29には取り込まれなかったけどなぁ。
0203デフォルトの名無しさん
NGNG0204デフォルトの名無しさん
NGNGまだ、わかってない部分が多いのですが、質問させてください。
汎用クラスを定義する際、通常のクラス定義のように CSample.h , CSample.cpp
のように宣言と定義を別ファイルにはできないのですか?
ウィザード利用によるクラス定義(一般クラスの作成手順)を行って、
後で、Template <class T> 文を
class CSample
宣言の前につけたり、いろいろしましたが、コンパイルが通りません。
(中間オブジェファイルができません)
結局、定義と宣言を分けないでヘッダファイルのみで全てを記述すれば、OKでした。
実際に汎用クラスを利用する際には、利用箇所によって型決定する事を考えれば
当然のような気もするんですが、そうなんでしょうか?
もしそうなら、複数のファイルで、同一の汎用クラスを利用する際は、利用するファイルに、
定義した汎用クラス全文をインクルードすることになるんでしょうか。
0205デフォルトの名無しさん
NGNG>複数のファイルで、同一の汎用クラスを利用する際は、
>利用するファイルに、定義した汎用クラス全文を
>インクルードすることになるんでしょうか
そうです
0206デフォルトの名無しさん
NGNG何度もガイシュツだが、exportキーワードを完全にサポートしている処理系
でなければ、template文の宣言と実体を別のファイルに分けて書くことはできない。
もしexportキーワードが有効であれば、実体部をライブラリにできることになる。
0207204
NGNGしかも、ガイシュツとのことで、もうしわけないです。
ありがとうございました。がんばってみます。
0208デフォルトの名無しさん
NGNGいう意見があるのですが、どちらが正しいのでしょうか。
ちなみにコンパイルはどちらでも通ります(gcc3.2)。
struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};
int main()
{
Test t;
t.func(1, 1); // as <int, int>
t.func(1.1, 2.2); // as <double, double>
t.func<int, double>(2, 3.3); //1
t.template func<int, double>(2, 3.3); //2
}
0209デフォルトの名無しさん
NGNGメンバ関数テンプレートはtと同一のスコープの時は
大丈夫ですが、パラメータとしてtをどこかへ渡すと
t.template と書く必要があります。
0210デフォルトの名無しさん
NGNG大丈夫なようですが・・・・・意味を勘違いしてるかな?
struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};
void abc(Test& t)
{
t.func(1, 1.1);
}
int main()
{
Test t;
abc(t);
}
0211デフォルトの名無しさん
NGNGあんまり適当なことを言うのもあれなんで識者の人に
聞きたいところだけど、
基本的には型推論できるところは.templateは要らないと思った。
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
に書いてあったんだけど、900番台がなぜか抜けてるんだよね。。。
これ以上は分りません。すんまそん。
0212デフォルトの名無しさん
NGNGわざわざすみません。いろいろ実験してみたら、下のエラーとコメントしてある
行で、'<'がどうも比較演算子とコンパイラが勘違いしてエラーになるようです。
こういう場合、template限定子を付けて、後に続く'<'が型名のパラメータの
始まりである事を示さなければならないようです。
まだよくわかってないのですが、さらに実験してみます。
struct Test {
template <typename T, typename U>
T test(U x) {
std::cout << typeid(T).name() << ' ' << typeid(x).name() << std::endl;
return static_cast<T>(x);
}
};
template <typename T>
T abc(T x)
{
Test t;
T y;
// y = t.test<T>(x); // エラー
y = t.template test<T>(x);
return y;
}
int main()
{
abc(1.1);
}
0213デフォルトの名無しさん
NGNG0214デフォルトの名無しさん
NGNGそれはコンパイラのバグだと思う…。
> template <typename T>
> T abc(T x)
> {
> Test t;
> T y;
> y = t.test<T>(x); // エラー
だと t の型はtemplateパラメータ T に依存せずに決定しているので、
わざわざ template 限定子を入れる必要はないはず。t の型が T に
依存するなら、test がメンバ関数 template であることはパース時には
わからんから、明示的な template 限定子が必要になるけれど。
例えばもし
> template <typename Y>
> struct Test {
で
> T abc(T x)
> {
> Test<T> t;
だったら、tの型がTに依存するので、必要。
0215デフォルトの名無しさん
NGNG機能と優先順位は
1.内部で管理しているテクスチャのハンドル数が最大数を超えたら最も古いハンドルを開放する。
2.sjisのコードを指定するとデータ構造からテクスチャのハンドルを検索して返す。
3.ハンドルが存在しなければその時点でテクスチャを生成してそのハンドルを返す。
で、要素の構造体はこんな感じです。
struct{
unsigned short Code; /// 文字コード
void *Handle; /// テクスチャハンドル
};
要するにキャッシュの機構なんですがとりあえず
hashでインスタンスを、queueで参照を管理するというのを
思いついたんですが他に効率的な方法はありますか?
0216bloom
NGNGhttp://www.agemasukudasai.com/bloom/
0217デフォルトの名無しさん
NGNGいろいろやってみたけど、templateパラメータは現れた順に解決される
みたいですね。
コンパイラはgcc3.2(MinGW)を使ってみたんですけど、やっぱりバグです
かね。プログラミング言語C++第3版§C.13.6、P971を読んでいたら、メンバ
テンプレートの型の推定が不可能な場合、メンバ関数名の次に現れる
"<"を比較演算子と見なしてしまいコンパイルエラーになるような事が
書いてありました。
でもそのような事はまれなので、エラーが生じた場合のみtemplate限定子
を付けるようにしようと思います。
0218デフォルトの名無しさん
NGNGオソレスだが、次のようにするとVC7でも分割できる。
--- T.h ---
template <typename T>
void print(const T&);
--- T.cpp ---
#include <iostream>
#include "T.h"
template <typename T>
void print(const T& t)
{ std::cout << t << std::endl; }
template void print<int>(const int&);
--- main.cpp ---
#include "T.h"
int main()
{
int i = 10;
print(i);
return 0;
}
0219デフォルトの名無しさん
NGNGtemplate にする意味あんまりないじゃん。
0220204
NGNGありがとうございます。動きました。
この場合、T.cpp をコンパイルする際には、実際の利用時の型を T.cpp 内部で明確にし、
それぞれの型別動作をオブジェファイルに記述している。と考えていいんですよね。
main 部に { double d ; print d } を追加するとリンクできないが、
T.cpp に template void print<double>(const double&); を記述すると正常動作したので、
このように解釈しました。
0221デフォルトの名無しさん
NGNGたしかに、語源的な意味しか残ってないわな。
>>220
おおむね合ってます。「明示的なインスタンス化」っていうやつですわ。
0222デフォルトの名無しさん
NGNG↓
プレコンパイル
↓
ソース内包オブジェクトファイル
↓
リンク
↓
ソース内包リンクドモジュール
↓
ポストコンパイル
↓
ロードモジュール
という方式にすれば、export 対応はそんなに難しくないと思うんだけど・・・。
0223デフォルトの名無しさん
NGNG簡単に逆コンパイルできちゃうような代物だと、そもそも export 使う意味が無いと
思うんだが。速度の話なら pre compiled header って手もあるわけだし。
0224デフォルトの名無しさん
NGNG0225デフォルトの名無しさん
NGNGでさ、、、、
どれが一番速いの?
0226デフォルトの名無しさん
NGNG0227デフォルトの名無しさん
NGNG0228デフォルトの名無しさん
NGNGBoundsCheckerがSTLportのアロケータ(たぶん)みたいなところで
メモリリークを検出してくれます。
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
std::string hello = "Hello, world!";
std::cout << hello << std::endl;
return 0;
}
こんなコードでも1600バイトのリークが検出されます。
_STLP_USE_NEWALLOCマクロを使えば出なくなるんですが、遅くなりそうだなー
ってのと、Configuration Manualに
When using tools like Purify (c), Codeguard (c) or BoundsChecker (c),
it is advised to #define _STLP_USE_MALLOC or _STLP_USE_NEWALLOC,
otherwise pointer checking will generally not be available on most STL
internal structures, thus defeating the purpose of those tools.
とあるので気にしなくていいってことなんでしょうか?
0229デフォルトの名無しさん
NGNG気にするな。
0230デフォルトの名無しさん
NGNG実際STLportのdefault allocatorは一度確保したら絶対返さない。
> とあるので気にしなくていいってことなんでしょうか?
時と場合で気にしたりしなかったり
allocatorつかったらmallocされっぱなしでも困らないならそのまま
返してくれなきゃ困る場合はSTLP_USE_MALLOCとか
自前でallocator用意すれ
0231デフォルトの名無しさん
NGNG0232学習能力の無い人
NGNG何で無いの?
毎回const map作って[]使おうとすると怒られるから
constはずすってことをつい繰り返しちゃうんだけど・・・。
0233デフォルトの名無しさん
NGNGstd::mapの[]演算子は、対応するキーがないと、自動的に挿入する仕様になって
いるから。その時点で既にconstでは無い。
[]が便利な事は認めるが、できるだけfindとinsertを使おう。例えばstd::multimapには
[]演算子が無い。仕様をよく考えると当然だが、最初この事を知ったとき、STLには
設計ミスがあるのではないかと思ってしまった。
0234デフォルトの名無しさん
NGNG理由があるの?
0235デフォルトの名無しさん
NGNG効率。
0236デフォルトの名無しさん
NGNGコード量が増える割には、見合った効果が得られないけど?
初期要素 500,000、試行回数 5,000,000 で試してみた。
挿入が全く発生しない状況でも、1 % 程しか遅くならない。
挿入しか発生しない場合は 5 % 程遅い。
それとも、漏れの書き方が悪い?
int r = large_rand();
map<int, int>::iterator itr = m2.find(r);
if(itr == m2.end())
itr = m2.insert(pair<int, int>(r, 0)).first;
return itr->second;
0237デフォルトの名無しさん
NGNG0238デフォルトの名無しさん
NGNGfind,insertではコピーコンストラクタが呼ばれて
[]演算子だとデフォルトコンストラクタが呼ばれた後に
=演算子が呼び出されるんだな。
だからintではなくもっと複雑な型じゃないと差は出ないのかも。
逆に、find,insertでは二回検索するので余計に遅くなりそうな気がするのだが
236の結果を見るとそうでもないのが不思議。
0239237
NGNG> find,insertでは二回検索するので余計に遅くなりそうな気がするのだが
漏れも最初そう思ったけど、find が意外に速いんだよね。
ちなみに、[] の実装はこうだったよ。
_Tref operator[](const key_type& _Kv)
{
iterator _P = insert(value_type(_Kv, _Ty())).first;
return ((*_P).second);
}
つまり、236 のコードの、if より下と全く同等。
だから、テストでは find のミスヒット分だけ遅くなったという事だね。
> find,insertではコピーコンストラクタが呼ばれて
> []演算子だとデフォルトコンストラクタが呼ばれた後に
> =演算子が呼び出されるんだな。
上に示した通り共通の動作をしているので、これは違うと思う。
0240238
NGNG何を思ったか[]演算子を使う方に
m2[r]=0;
みたいなコードを想像してた。
これじゃ動作が違うのに。
0241デフォルトの名無しさん
NGNGそんなタコな実装ねぇだろ。
その実装だと、
・二回検索することになる
・挿入しない場合にも一時オブジェクトの生成・破棄がおこなわれる。
0242239
NGNGVC6 に付属の STL をそのままかっぱらってきたんだが・・・。
ところで、どこが 2 重検索になるって?
0243241
NGNGおそろしい。
あ、二回検索にはならねぇな。
236と脳内ブレンドされてたよ。スマソ
0244デフォルトの名無しさん
NGNG* Hewlett-Packard Company
だと、
Allocator<T>::reference operator[](const key_type& k) {
return (*((insert(value_type(k, T()))).first)).second;
}
だな。
まぁ、なんだ。たしかに簡潔といえば簡潔だが……
0245デフォルトの名無しさん
NGNG0246デフォルトの名無しさん
NGNG0247デフォルトの名無しさん
NGNGどのようにされていますか?
0248デフォルトの名無しさん
NGNG0249デフォルトの名無しさん
NGNG何の話?
0250デフォルトの名無しさん
NGNGスレの趣旨から言って Generic プログラミングだろう(違うか)
0251デフォルトの名無しさん
NGNG0252デフォルトの名無しさん
NGNGusing namespace std;
template <typename T> struct dd :public T
{
typename typedef dd<T>::value_type char_type;
inline friend operator<(const dd<T>& a1,const dd<T>& a2 ); //(1)
inline friend operator<(const dd<T>& a1,const char_type* a2 );//(2)
dd(){}
~dd(){}
dd(const char_type* a){ *this=a;}
};
template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 )
{
return ((const T&)a1 < (const T&)a2);
}
template <typename T> bool operator<(const dd<T>& a1, const dd<T>::char_type* a2 )
{
return ((const T&)a1 < a2);
}
int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) NG
}
templateのoperatorで
(2)のような場合、実装をクラスの中に書くしかないのでしょうか?
0253デフォルトの名無しさん
NGNGdd(const char_type* a)
{
static_cast<T&>(*this)=a;
}
ですね。
追記:
friendなんだからクラス内に実装を書けということなのか、
friendの行を削除したらOKでした。
0254デフォルトの名無しさん
NGNG0255デフォルトの名無しさん
NGNG0256デフォルトの名無しさん
NGNGうまくいったよ。ddのコンストラクタはexplicit宣言しておかないと、(1)や(2)で
勝手にstd::operator< が選ばれて警告が出る。
template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};
0257デフォルトの名無しさん
NGNGinline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
return ((const T&)a1 < (const T&)a2);
}
template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
return ((const T&)a1 < a2);
}
int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
}
friend宣言で未解決のテンプレートパラメータがあると、非テンプレート関数として
コンパイルされてしまうらしいから、型特定して警告を回避した。
0258デフォルトの名無しさん
NGNGtemplate <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const typename dd<T>::char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};
0259デフォルトの名無しさん
NGNGinline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
std::cout << "dd<T> < dd<T>" << std::endl;
return ((const T&)a1 < (const T&)a2);
}
template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
std::cout << "dd<T> < dd<T>::char_type" << std::endl;
return ((const T&)a1 < a2);
}
int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK、しかし実行されない?
}
0260デフォルトの名無しさん
NGNG基底クラス(std::string)の operator<(const std::string&, const char*) が
呼ばれているようだな
通常の関数とテンプレート関数が多重定義されている場合、通常の関数が
優先されるからな
0261デフォルトの名無しさん
NGNGtemplate <typename T> struct dd :public T
{
typedef typename dd<T>::value_type char_type;
friend bool operator<(const char_type* a1, const dd<T>& a2 )
{
cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
return (a1 < (const T&)a2);
}
dd(){m_str="2ch";}
~dd(){}
explicit dd(const char_type* a)
{
dd::dd();
static_cast<T&>(*this)=a;//なんとm_strにaが入る
}
private:
string m_str;
};
0262続き
NGNG{
cout << "(1)" << endl;
return ((const T&)a1 < (const T&)a2);
}
template <typename T> bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2 )
{
cout << "(2)" << endl;
return ((const T&)a1 < a2);
}
int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
"abc" < D; //(3) OK
}
0263デフォルトの名無しさん
NGNG>cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
m_str は初期化時の空文のままだから、表示されないのは当たり前。
>static_cast<T&>(*this)=a;//なんとm_strにaが入る
そんなわけね〜だろ!
なんか、バカでっかい勘違いしてんぞ
0264引き篭もり
NGNG■ このスレッドは過去ログ倉庫に格納されています