トップページ⇒tech
1001コメント388KB

【C++】template 統合スレ -- STL/Boost/Loki, etc.

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。

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 あたりに。
0172デフォルトの名無しさんNGNG
>>21
ひどいことを言うなよ。お前だってアホだったろうが
0173デフォルトの名無しさんNGNG
>>172
ひどいことを言うなよ。
0174デフォルトの名無しさんNGNG
>>168
確か>>164の脳内コンパイルだと通りません。
0175デフォルトの名無しさんNGNG
ネタがないとスレが荒むな。
0176デフォルトの名無しさんNGNG
それもあるけど、昔と比べると荒れすぎ。
0177164NGNG
>>168,174
悪りィ、TとUが逆転してるのに気付かんかった。
っていうかテンプレ引数の交換は気付きにくいからやめい。
0178デフォルトの名無しさんNGNG
>>177
やめい、って交換しなきゃ第二引数が省略できんだろ。
0179デフォルトの名無しさんNGNG
>>178

template<class T, class U>
T hoge( U foo )
{
...
}

hoge<int>("できますが何か?");
0180160NGNG
>>177
ああ、なるほど。混乱させてすまなんだ。

U を使うのって Undeducible か何かの略かと思ってたんで>>144と
同じに返値U、引数T、になるようにtemplateの方を変えたんだけど、
Tの次はUってことか。自分では2引数以上のtemplateを書くときは
T1、T2、 T3 ... なのでなぁ。
0181デフォルトの名無しさんNGNG
>>179
コロンブス的な発想にチトワラタ(w
0182デフォルトの名無しさんNGNG
素朴な疑問なんだけど
template<class T, class U>
を
template<typename T, typename U>
とは書かないの?
0183160NGNG
>>182
個人的には、
・タイプ数減らしたい時はclass。
・template template parameter は class と書くので、
 何となく全部 class で統一したい気分の日は class。
・マジメに書くときはtypename。
0184デフォルトの名無しさんNGNG
漏れは最初に覚えたときにclassのみだったから
テンプレート引数はclassのみ使用。
typenameは
typedef typename T::iterator iterator;
とがぐらいしか使わない。
0185デフォルトの名無しさんNGNG
>>184
漏れはtypenameに直した。
ってか,intとかにも対応するのにclassって気持ち悪いんだよな。C++のintはクラスじゃないし。
0186184NGNG
>>185
気持ちは分かる。
0187デフォルトの名無しさんNGNG
昨夜、”C++ Templates" をゲット
まだChapter 3までしか読んでないけど、なかなか良さげ
0188デフォルトの名無しさんNGNG
>>187
どこの出版社?(・∀・)イイ?
0189デフォルトの名無しさんNGNG
>>189
Addison-Wesley だが……出たばっかの洋書でふ
0190189NGNG
× >>189
○ >>188
0191デフォルトの名無しさんNGNG
>>189
ありが�d。俺も本屋行って見てくるよ。
0192デフォルトの名無しさんNGNG
>Addison-Wesley だが…
Addison-Wesley キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!!
Addison-Wesley、もう大好き♪
分かりやすいし、詳しいし…。
0193デフォルトの名無しさんNGNG
>>183
俺は int などのプリミティブ型も引数に取る場合には typename, クラスしか
引数に取らん場合には class にしてる。まー、趣味の問題だね。
0194デフォルトの名無しさんNGNG
typename と class は全く同一だと聞いた事があるが・・・どこでだっけ?
0195デフォルトの名無しさんNGNG
本屋行ってみたが、洋書は置いてないと言われた。(´・ω・`)ショボーン
日本訳が出るまで最低1年はかかるからなー。
0196デフォルトの名無しさんNGNG
typename自体が無いしょぼーいコンパイラも世の中には存在する。
0197デフォルトの名無しさんNGNG
>196
まだ使ってるのか… 御愁傷様です。
0198デフォルトの名無しさんNGNG
>>194
全く同一だよ。だからみんなして趣味の問題とか個人的にはとか言ってるわけ。

>>195
出たばっかりの洋書はWebで買った方が良いと思う。
0199デフォルトの名無しさんNGNG
VC6sp5にも移植が出来たみたいです
http://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport
0200デフォルトの名無しさんNGNG
>>199
がいしゅつ
http://pc3.2ch.net/test/read.cgi/tech/1035005882/766
0201デフォルトの名無しさんNGNG
boost::lexical_castで、スペースを含む文字列を変換すると例外が
出ますな。

std::cout << boost::lexical_cast<char*>(std::string("abc def")) << std::endl;
std::cout << boost::lexical_cast<std::string>("abc def") << std::endl;

boost::lexical_castはstd::stringstreamを使って実装しているので、
>>演算子や<<演算子がスペースを区切り文字とみなしてしまう故らしい。
何とかして欲しいですな。
0202デフォルトの名無しさんNGNG
>>201
http://groups.yahoo.com/group/boost/files/lexical_cast_proposition/
…では直ってるので1.30では修正が取り込まれると思いたい。
と言いながら結局1.29には取り込まれなかったけどなぁ。
0203デフォルトの名無しさんNGNG
落ちそうなので一回ageます。
0204デフォルトの名無しさんNGNG
昨日からSTLの勉強をVC++.Netで始めました。
まだ、わかってない部分が多いのですが、質問させてください。

汎用クラスを定義する際、通常のクラス定義のように CSample.h , CSample.cpp
のように宣言と定義を別ファイルにはできないのですか?

ウィザード利用によるクラス定義(一般クラスの作成手順)を行って、
後で、Template <class T> 文を
class CSample
宣言の前につけたり、いろいろしましたが、コンパイルが通りません。
(中間オブジェファイルができません)

結局、定義と宣言を分けないでヘッダファイルのみで全てを記述すれば、OKでした。

実際に汎用クラスを利用する際には、利用箇所によって型決定する事を考えれば
当然のような気もするんですが、そうなんでしょうか?

もしそうなら、複数のファイルで、同一の汎用クラスを利用する際は、利用するファイルに、
定義した汎用クラス全文をインクルードすることになるんでしょうか。
0205デフォルトの名無しさんNGNG
>>204
>複数のファイルで、同一の汎用クラスを利用する際は、
>利用するファイルに、定義した汎用クラス全文を
>インクルードすることになるんでしょうか
そうです
0206デフォルトの名無しさんNGNG
>>204
何度もガイシュツだが、exportキーワードを完全にサポートしている処理系
でなければ、template文の宣言と実体を別のファイルに分けて書くことはできない。

もしexportキーワードが有効であれば、実体部をライブラリにできることになる。
0207204NGNG
やっぱりそうだったんですね。
しかも、ガイシュツとのことで、もうしわけないです。
ありがとうございました。がんばってみます。
0208デフォルトの名無しさんNGNG
物の本によれば、//1の書き方は正しくなく、//2のように書かなければならないと
いう意見があるのですが、どちらが正しいのでしょうか。
ちなみにコンパイルはどちらでも通ります(gcc3.2)。

struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};

int main()
{
Test t;
t.func(1, 1); // as <int, int>
t.func(1.1, 2.2); // as <double, double>
t.func<int, double>(2, 3.3); //1
t.template func<int, double>(2, 3.3); //2
}
0209デフォルトの名無しさんNGNG
>>208
メンバ関数テンプレートはtと同一のスコープの時は
大丈夫ですが、パラメータとしてtをどこかへ渡すと
t.template と書く必要があります。
0210デフォルトの名無しさんNGNG
>>209
大丈夫なようですが・・・・・意味を勘違いしてるかな?

struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};

void abc(Test& t)
{
t.func(1, 1.1);
}

int main()
{
Test t;

abc(t);
}
0211デフォルトの名無しさんNGNG
>>210
あんまり適当なことを言うのもあれなんで識者の人に
聞きたいところだけど、
基本的には型推論できるところは.templateは要らないと思った。
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
に書いてあったんだけど、900番台がなぜか抜けてるんだよね。。。

これ以上は分りません。すんまそん。
0212デフォルトの名無しさんNGNG
>>210
わざわざすみません。いろいろ実験してみたら、下のエラーとコメントしてある
行で、'<'がどうも比較演算子とコンパイラが勘違いしてエラーになるようです。

こういう場合、template限定子を付けて、後に続く'<'が型名のパラメータの
始まりである事を示さなければならないようです。

まだよくわかってないのですが、さらに実験してみます。

struct Test {
template <typename T, typename U>
T test(U x) {
std::cout << typeid(T).name() << ' ' << typeid(x).name() << std::endl;
return static_cast<T>(x);
}
};

template <typename T>
T abc(T x)
{
Test t;
T y;
// y = t.test<T>(x); // エラー
y = t.template test<T>(x);
return y;
}

int main()
{
abc(1.1);
}
0213デフォルトの名無しさんNGNG
スマソ>>211さんに対してのレスです。
0214デフォルトの名無しさんNGNG
>>212
それはコンパイラのバグだと思う…。

> template <typename T>
> T abc(T x)
> {
> Test t;
> T y;
> y = t.test<T>(x); // エラー

だと t の型はtemplateパラメータ T に依存せずに決定しているので、
わざわざ template 限定子を入れる必要はないはず。t の型が T に
依存するなら、test がメンバ関数 template であることはパース時には
わからんから、明示的な template 限定子が必要になるけれど。

例えばもし
> template <typename Y>
> struct Test {
で
> T abc(T x)
> {
> Test<T> t;
だったら、tの型がTに依存するので、必要。
0215デフォルトの名無しさんNGNG
漢字のテクスチャを管理するデータ構造を作りたいです。
機能と優先順位は
1.内部で管理しているテクスチャのハンドル数が最大数を超えたら最も古いハンドルを開放する。
2.sjisのコードを指定するとデータ構造からテクスチャのハンドルを検索して返す。
3.ハンドルが存在しなければその時点でテクスチャを生成してそのハンドルを返す。
で、要素の構造体はこんな感じです。
struct{
unsigned short Code; /// 文字コード
void *Handle; /// テクスチャハンドル
};

要するにキャッシュの機構なんですがとりあえず
hashでインスタンスを、queueで参照を管理するというのを
思いついたんですが他に効率的な方法はありますか?
0216bloomNGNG

http://www.agemasukudasai.com/bloom/
0217デフォルトの名無しさんNGNG
>>214
いろいろやってみたけど、templateパラメータは現れた順に解決される
みたいですね。

コンパイラはgcc3.2(MinGW)を使ってみたんですけど、やっぱりバグです
かね。プログラミング言語C++第3版§C.13.6、P971を読んでいたら、メンバ
テンプレートの型の推定が不可能な場合、メンバ関数名の次に現れる
"<"を比較演算子と見なしてしまいコンパイルエラーになるような事が
書いてありました。

でもそのような事はまれなので、エラーが生じた場合のみtemplate限定子
を付けるようにしようと思います。
0218デフォルトの名無しさんNGNG
>>204
オソレスだが、次のようにするとVC7でも分割できる。

--- T.h ---
template <typename T>
void print(const T&);

--- T.cpp ---
#include <iostream>
#include "T.h"

template <typename T>
void print(const T& t)
{    std::cout << t << std::endl; }

template void print<int>(const int&);

--- main.cpp ---
#include "T.h"

int main()
{
   int i = 10;
   print(i);

   return 0;
}
0219デフォルトの名無しさんNGNG
> template void print<int>(const int&);

template にする意味あんまりないじゃん。
0220204NGNG
>218
ありがとうございます。動きました。

この場合、T.cpp をコンパイルする際には、実際の利用時の型を T.cpp 内部で明確にし、
それぞれの型別動作をオブジェファイルに記述している。と考えていいんですよね。

main 部に { double d ; print d } を追加するとリンクできないが、
T.cpp に template void print<double>(const double&); を記述すると正常動作したので、
このように解釈しました。
0221デフォルトの名無しさんNGNG
>>219
たしかに、語源的な意味しか残ってないわな。

>>220
おおむね合ってます。「明示的なインスタンス化」っていうやつですわ。
0222デフォルトの名無しさんNGNG
ソースファイル
↓
プレコンパイル
↓
ソース内包オブジェクトファイル
↓
リンク
↓
ソース内包リンクドモジュール
↓
ポストコンパイル
↓
ロードモジュール

という方式にすれば、export 対応はそんなに難しくないと思うんだけど・・・。
0223デフォルトの名無しさんNGNG
>222
簡単に逆コンパイルできちゃうような代物だと、そもそも export 使う意味が無いと
思うんだが。速度の話なら pre compiled header って手もあるわけだし。
0224デフォルトの名無しさんNGNG
export って逆コンパイルと何か関係あるの?
0225デフォルトの名無しさんNGNG


でさ、、、、

どれが一番速いの?
0226デフォルトの名無しさんNGNG
何の話?
0227デフォルトの名無しさんNGNG
どのライブラリが一番効率よいかってこと。

0228デフォルトの名無しさんNGNG
STLport 4.5.3をVC6sp5で使おうと思ってインストールしたんですが、
BoundsCheckerがSTLportのアロケータ(たぶん)みたいなところで
メモリリークを検出してくれます。

#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
  std::string hello = "Hello, world!";
  std::cout << hello << std::endl;
  return 0;
}
こんなコードでも1600バイトのリークが検出されます。
_STLP_USE_NEWALLOCマクロを使えば出なくなるんですが、遅くなりそうだなー
ってのと、Configuration Manualに

When using tools like Purify (c), Codeguard (c) or BoundsChecker (c),
it is advised to #define _STLP_USE_MALLOC or _STLP_USE_NEWALLOC,
otherwise pointer checking will generally not be available on most STL
internal structures, thus defeating the purpose of those tools.

とあるので気にしなくていいってことなんでしょうか?
0229デフォルトの名無しさんNGNG
>228
気にするな。
0230デフォルトの名無しさんNGNG
>>228

実際STLportのdefault allocatorは一度確保したら絶対返さない。

> とあるので気にしなくていいってことなんでしょうか?

時と場合で気にしたりしなかったり

allocatorつかったらmallocされっぱなしでも困らないならそのまま

返してくれなきゃ困る場合はSTLP_USE_MALLOCとか
自前でallocator用意すれ
0231デフォルトの名無しさんNGNG
Effective STLなかなか良さげ
0232学習能力の無い人NGNG
mapにconst reference operator[]() constって
何で無いの?
毎回const map作って[]使おうとすると怒られるから
constはずすってことをつい繰り返しちゃうんだけど・・・。
0233デフォルトの名無しさんNGNG
>>232
std::mapの[]演算子は、対応するキーがないと、自動的に挿入する仕様になって
いるから。その時点で既にconstでは無い。

[]が便利な事は認めるが、できるだけfindとinsertを使おう。例えばstd::multimapには
[]演算子が無い。仕様をよく考えると当然だが、最初この事を知ったとき、STLには
設計ミスがあるのではないかと思ってしまった。
0234デフォルトの名無しさんNGNG
対応するキーがないと自動的に挿入する、という機能が欲しい時に [] を使わない
理由があるの?
0235デフォルトの名無しさんNGNG
>234
効率。
0236デフォルトの名無しさんNGNG
>>235
コード量が増える割には、見合った効果が得られないけど?

初期要素 500,000、試行回数 5,000,000 で試してみた。
挿入が全く発生しない状況でも、1 % 程しか遅くならない。
挿入しか発生しない場合は 5 % 程遅い。

それとも、漏れの書き方が悪い?

int r = large_rand();
map<int, int>::iterator itr = m2.find(r);
if(itr == m2.end())
itr = m2.insert(pair<int, int>(r, 0)).first;
return itr->second;
0237デフォルトの名無しさんNGNG
つーか、233 の 「例えば」 の前後が繋がってないよ。
0238デフォルトの名無しさんNGNG
236のコードを見て気が付いたが、
find,insertではコピーコンストラクタが呼ばれて
[]演算子だとデフォルトコンストラクタが呼ばれた後に
=演算子が呼び出されるんだな。

だからintではなくもっと複雑な型じゃないと差は出ないのかも。

逆に、find,insertでは二回検索するので余計に遅くなりそうな気がするのだが
236の結果を見るとそうでもないのが不思議。
0239237NGNG
>>238
> find,insertでは二回検索するので余計に遅くなりそうな気がするのだが

漏れも最初そう思ったけど、find が意外に速いんだよね。
ちなみに、[] の実装はこうだったよ。

_Tref operator[](const key_type& _Kv)
{
 iterator _P = insert(value_type(_Kv, _Ty())).first;
 return ((*_P).second);
}

つまり、236 のコードの、if より下と全く同等。
だから、テストでは find のミスヒット分だけ遅くなったという事だね。

> find,insertではコピーコンストラクタが呼ばれて
> []演算子だとデフォルトコンストラクタが呼ばれた後に
> =演算子が呼び出されるんだな。

上に示した通り共通の動作をしているので、これは違うと思う。
0240238NGNG
スマソ、勘違いしてた。
何を思ったか[]演算子を使う方に

m2[r]=0;

みたいなコードを想像してた。
これじゃ動作が違うのに。
0241デフォルトの名無しさんNGNG
>>239
そんなタコな実装ねぇだろ。
その実装だと、
・二回検索することになる
・挿入しない場合にも一時オブジェクトの生成・破棄がおこなわれる。
0242239NGNG
> そんなタコな実装ねぇだろ。

VC6 に付属の STL をそのままかっぱらってきたんだが・・・。
ところで、どこが 2 重検索になるって?
0243241NGNG
ほんとだ>VC6
おそろしい。

あ、二回検索にはならねぇな。
236と脳内ブレンドされてたよ。スマソ
0244デフォルトの名無しさんNGNG
* Copyright (c) 1994
* Hewlett-Packard Company
だと、
Allocator<T>::reference operator[](const key_type& k) {
 return (*((insert(value_type(k, T()))).first)).second;
}
だな。
まぁ、なんだ。たしかに簡潔といえば簡潔だが……
0245デフォルトの名無しさんNGNG
std::mapのoperator[]は特異な存在だけど、便利であるがゆえによく使う。
0246デフォルトの名無しさんNGNG
コードがかさばってでも速い方がいいというなら、C++ を使う理由はない。
0247デフォルトの名無しさんNGNG
STLportのstd::bit_vectorと、Boostのboost::dynamic_bitsetの使い分けは
どのようにされていますか?
0248デフォルトの名無しさんNGNG
コードがかさばっても速さと汎用性が両立できるなら、C++を使う理由になる。
0249デフォルトの名無しさんNGNG
> 汎用性

何の話?
0250デフォルトの名無しさんNGNG
>249
スレの趣旨から言って Generic プログラミングだろう(違うか)
0251デフォルトの名無しさんNGNG
vc++ver7.0でもtupleは使えない。ok?
0252デフォルトの名無しさんNGNG
#include<string>
using namespace std;

template <typename T> struct dd :public T
{
typename typedef dd<T>::value_type char_type;
inline friend operator<(const dd<T>& a1,const dd<T>& a2 ); //(1)
inline friend operator<(const dd<T>& a1,const char_type* a2 );//(2)
dd(){}
~dd(){}
dd(const char_type* a){ *this=a;}
};

template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 )
{
return ((const T&)a1 < (const T&)a2);
}

template <typename T> bool operator<(const dd<T>& a1, const dd<T>::char_type* a2 )
{
return ((const T&)a1 < a2);
}

int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) NG
}
templateのoperatorで
(2)のような場合、実装をクラスの中に書くしかないのでしょうか?
0253デフォルトの名無しさんNGNG
修正:
dd(const char_type* a)
{
static_cast<T&>(*this)=a;
}
ですね。
追記:
friendなんだからクラス内に実装を書けということなのか、
friendの行を削除したらOKでした。
0254デフォルトの名無しさんNGNG
テンプレートクラスはfriendをメンバに取ることはできないね。
0255デフォルトの名無しさんNGNG
しまった、テンプレートクラスもfriendはメンバに取れるね。逝ってくる・・・
0256デフォルトの名無しさんNGNG
>>252>>253
うまくいったよ。ddのコンストラクタはexplicit宣言しておかないと、(1)や(2)で
勝手にstd::operator< が選ばれて警告が出る。

template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};
0257デフォルトの名無しさんNGNG
template <typename T>
inline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
return ((const T&)a1 < (const T&)a2);
}

template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
return ((const T&)a1 < a2);
}

int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
}

friend宣言で未解決のテンプレートパラメータがあると、非テンプレート関数として
コンパイルされてしまうらしいから、型特定して警告を回避した。
0258デフォルトの名無しさんNGNG
でもまだおかしいや。(2)が実行されてないようです。

template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const typename dd<T>::char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};
0259デフォルトの名無しさんNGNG
template <typename T>
inline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
std::cout << "dd<T> < dd<T>" << std::endl;
return ((const T&)a1 < (const T&)a2);
}

template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
std::cout << "dd<T> < dd<T>::char_type" << std::endl;
return ((const T&)a1 < a2);
}

int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK、しかし実行されない?
}
0260デフォルトの名無しさんNGNG
>>259
基底クラス(std::string)の operator<(const std::string&, const char*) が
呼ばれているようだな
通常の関数とテンプレート関数が多重定義されている場合、通常の関数が
優先されるからな
0261デフォルトの名無しさんNGNG
継承したクラスのオブジェクトは自分自身を指すのだね。
template <typename T> struct dd :public T
{
typedef typename dd<T>::value_type char_type;
friend bool operator<(const char_type* a1, const dd<T>& a2 )
{
cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
return (a1 < (const T&)a2);
}
dd(){m_str="2ch";}
~dd(){}
explicit dd(const char_type* a)
{
dd::dd();
static_cast<T&>(*this)=a;//なんとm_strにaが入る
}
private:
string m_str;
};
0262続きNGNG
template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 )
{
cout << "(1)" << endl;
return ((const T&)a1 < (const T&)a2);
}
template <typename T> bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2 )
{
cout << "(2)" << endl;
return ((const T&)a1 < a2);
}
int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
"abc" < D; //(3) OK
}
0263デフォルトの名無しさんNGNG
>>261
>cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
m_str は初期化時の空文のままだから、表示されないのは当たり前。
>static_cast<T&>(*this)=a;//なんとm_strにaが入る
そんなわけね〜だろ!

なんか、バカでっかい勘違いしてんぞ

0264引き篭もりNGNG
レベルたけぇ・・・(-_-)
0265デフォルトの名無しさんNGNG
int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < std::string("abc";) //(2) OK
}

のように、sts::stringの一時変数を作って渡してやらないと、テンプレート関数
の方を呼んでくれない。この当たりがテンプレートの限界なのか。
0266デフォルトの名無しさんNGNG
しかし、ちょっと疑問なのだが、

explicit dd(const typename dd<T>::char_type& a){
static_cast<T&>(*this) = a;
}

これって一体どこに代入しているの?どうみても自分自身に代入しているように
しか見えないのだが・・・・・どんな意味があるのだろう。
0267デフォルトの名無しさんNGNG
基本的な質問です。
More Effective C++のp.16、l2に実際のプログラムでは、このようなクラスはテンプレートになるのだが、
とあります。具体的にはどのように書けばいいのでしょうか?
0268デフォルトの名無しさんNGNG
>>266
なんか激しく気持ち悪い書き方だなぁ。
*(static_cast<T*>(this)) = a;
あるいはすなおに
T::operator=(a);
と書いたほうがわかりやすくないかい?
0269デフォルトの名無しさんNGNG
>>267
たんに、要素の型を int きめうちじゃなくてテンプレート引数で
指定できるようにすべきだ、ってことじゃないの?
0270デフォルトの名無しさんNGNG
>>268
というか、素直にこうだろ〜
explicit dd(const typename dd<T>::char_type& a) : T(a) { }
0271デフォルトの名無しさんNGNG
266です。
>>268>>270 やっはりそうですよね。分かりやすく書くことを心がけるようにします。
■ このスレッドは過去ログ倉庫に格納されています