トップページ⇒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 あたりに。
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 やっはりそうですよね。分かりやすく書くことを心がけるようにします。
0272デフォルトの名無しさんNGNG
dd::dd();//このあとすぐにdd::~dd()が呼ばれてるみたい。
static_cast<T&>(*this)=a;//だからm_strは空白になってる。
なんかすごい勘違いしてたな。絶対変だと薄々思ってたけど...

コンストラクタからコンストラクタを呼ぶと直後にデストラクタが呼び出されるのか。

struct A :public string
{
string m_str;
A()
{
m_str="2ch";
cout << "A::A()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
A(const char* c) :string(c)
{
A::A();
cout << "A::A(const char*)"<< endl;
}
};

int main()
{
A a("stu");
}


0273デフォルトの名無しさんNGNG
>>272
ちょっと違う。A::A(); と書くと、コンストラクタを呼び出したことにはならない。
単にAの一時変数が作成されてすぐに破棄されるだけ。

明示的にコンストラクタを呼び出すには、コンストラクタ初期化子を使う
しかない。
0274デフォルトの名無しさんNGNG
>A(const char* c) :string(c)
これ、: m_str(c) の間違いではなくて?
こういう書き方あるの?
0275デフォルトの名無しさんNGNG
>>273
なるほど!

>>274
A は stringを継承して、メンバも持っているから...。

A(const char* c) :string(c),m_str("m_str")
{
cout << static_cast<string>(*this) << endl;//stu
cout << m_str << endl;//m_str
}
0276デフォルトの名無しさんNGNG
明示的に呼ぶ場合、
this->A::A();
これならOKなのでは?
0277デフォルトの名無しさんNGNG
>>276
エラーっしょ。
0278デフォルトの名無しさんNGNG
>>277
できるよ。


#include <iostream>

using namespace std;

struct clsA
{
clsA(){cout<<"clsA():"<<hex<<(unsigned int)this<<endl;}
clsA(int){cout<<"clsA(int):"<<hex<<(unsigned int)this<<endl;
cout<<"CASE:clsA::clsA()"<<endl;clsA::clsA();
cout<<"CASE:this->clsA::clsA()"<<endl;this->clsA::clsA();}
};

void main(void)
{
clsA a(int());
}
0279デフォルトの名無しさんNGNG
>>278
コンパイラは何を使った?Borland-C++5.6.2及びgcc3.2(MinGW)は
エラーが出て通らないけど。
0280278NGNG
>>279
そうなの?
VC5(苦笑)でつ。
M$オンリーの機能なのか?
エラーはどんなの?
0281デフォルトの名無しさんNGNG
>>280
BCC5.6.2の場合。
エラー E2316 constructor2.cpp 12: 'clsA' は 'clsA' のメンバーではない(関数 clsA::clsA(int) )

gcc3.2(MinGW)の場合。
C:/MinGW/Learn/constructor2.cpp: In constructor `clsA::clsA(int)':
C:/MinGW/Learn/constructor2.cpp:12: parse error before `;' token

というエラーです。
0282278NGNG
>>281
わざわざTHXです。
…う〜ん。いよいよM$の仕様のような気が。
参考書引っ張り出してもう一度調べてみマフ...
0283デフォルトの名無しさんNGNG
>>282
俺も調べてみるが、確かコンストラクタからコンストラクタを呼び出すには、
初期化リストしか方法がなかったように記憶しているが・・・・どうだったっけな
0284デフォルトの名無しさんNGNG
>>282
どっかのメーリングリストではVC固有の機能だと言われてたな。

>>283
ちょっと話は変わるけど、こんなのどう?

static_cast<T*>(this)->~T();
new(this)T(param);

newで例外が起きるとヤバイが。
0285デフォルトの名無しさんNGNG
>>284
newの配置構文ですね。この場合、デストラクタは自分で呼び出してやらないと
いけないですね。
0286デフォルトの名無しさんNGNG
>>285
だから直前に呼んでるみたいだが
0287デフォルトの名無しさんNGNG
>>285
そうか? 
この場合、Tは(*this) の型の基底クラスだろ
この型のデストラクタがデフォで ~T() 呼ぶから
大丈夫だと思うんだが、どうよ

>>286
ちょっと、目の付け所がいまいち
0288デフォルトの名無しさんNGNG
>>287
そっか。そう言われればそうだな。途中でリコンストラクトした事にはコンパイラ
は気づいてないだろうからね。
0289デフォルトの名無しさんNGNG
>>269 ありが�d
0290デフォルトの名無しさんNGNG
>>284
× new(this)T(param);
○ new (static_cast<T*>(this)) T(param);
0291デフォルトの名無しさんNGNG
// こんな感じ?
#include <iostream>
using namespace std;

struct Base {
 Base() {
  cout << "Base::Base()" << endl;
 }
 virtual ~Base() {
  cout << "Base::~Base()" << endl;
 }
};

struct Ero : public Base {
 Ero() {
  cout << "エロ::エロ()" << endl;
 }
 ~Ero() {
  cout << "エロ::~エロ()" << endl;
 }
 Ero(int) {
  Base::~Base();
  new(this) Ero();
  cout << "エロ::エロ(int)" << endl;
 }
};

void main() {
 Ero ero(0); // エロ(0)
}
0292デフォルトの名無しさんNGNG
>>291
実行結果が次のようになったのだが、大丈夫だろうか?

Base::Base()
エロ::~エロ() //←これヤバくない?
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()
0293デフォルトの名無しさんNGNG
>>291
// ぜんぜん違うぞ、こうだ
#include <iostream>
class Foo
{
   int m;
public:
   Foo(int n = 0) : m(n)
   {   std::cout << "Foo is created by " << n << std::endl; }
   int val() const { return m; }
   ~Foo()
   {   std::cout << "Foo is destroyed. m = " << m << std::endl; }
};

template <typename T> class Bar : public T
{
public:
   Bar (int n = 0)
   {
       std::cout << "Bar is created by " << n << std::endl;
       static_cast<T*>(this)->~T();
       new (static_cast<T*>(this)) T(n);
   }
   ~Bar()
   {   std::cout << "Bar is destroyed." << std::endl; }
};

int main()
{
   Bar<Foo>(10);
}
0294293NGNG
今気づいたが、
テンプレート使う必然性無く、まったくレス違いなネタのような……
0295デフォルトの名無しさんNGNG
>>293
ををををぉぉぉぉなんとトリッキーな。

Fooのインスタンスが先に生成されるのが意外だったけど、これは使えそうだね。
0296291NGNG
>>292
やばいです。
つーか、うち(VC7)ではこうなりました。
仮想関数テーブルの取り出し方が違うのでしょうか?

Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()

>>293
飛び入りな者でスミマセン。
0297デフォルトの名無しさんNGNG
>>296
>>292はBorland-C++5.6.2です。
gcc3.2(MinGW)でやったら、次のようなエラーが出てコンパイルできませんでした。

C:/MinGW/Learn/constructor3.cpp: In constructor `Ero::Ero(int)':
C:/MinGW/Learn/constructor3.cpp:20: cannot call destructor `Base::~Base'
without object
0298デフォルトの名無しさんNGNG
gcc3.2(MinGW)は次のようにしたらコンパイルできて、実行結果は以下の通りです。

Ero(int) {
this->Base::~Base(); // thisから呼び出すようにした
new(this) Ero();
std::cout << "エロ::エロ(int)" << std::endl;
}

Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)

コンパイラによって実行結果がバラバラですね(^_^;)。
0299デフォルトの名無しさんNGNG
昨日から Modern C++ Design 読み始めたがなんだか
出じゃブーが多いなあ。
0300デフォルトの名無しさんNGNG
Phoenix Singleton とかな(藁
0301デフォルトの名無しさんNGNG
>>298
>コンパイラによって実行結果がバラバラですね(^_^;)。
データレイアウトの違いが原因かも(根拠なし)
0302デフォルトの名無しさんNGNG
>>300
300getしてるよ。
2〜3年前に似たようなこと頑張って考えてた時期あった。
基本型とユザ定義型の区別とか。
コンパイル時のじゃなくて実行時に区別するやつ。
ただしおれは目的があくまでパズルだった。
実用にしようと思ってたらなんか結果出てたかな...?
0303デフォルトの名無しさんNGNG
これって、メモリリークしちゃうの?
しないですよね?
void foo() {
    std::vector<std::string> v;
    v.push_back( *(new std::string("お兄ちゃん♥") );
}
0304デフォルトの名無しさんNGNG
Clear()
{
  for(std::vector<std::string>::iterator it=v.begin(); it!=v.end, ++it)
    delete &(*it);
  v.clear();
}

とかやらないと駄目なんじゃない?
0305デフォルトの名無しさんNGNG
>>304
(*it)はnewで作成したstringを
コピーコンストラクタでコピーした物だからダメだと思うが。
0306303NGNG
>>304-305
えっと、つまり、
void foo() {
string* p;
std::vector<std::string> v;
v.push_back( *(p = new std::string("美幸...おまえ...") );
delete p;
}
ってやらなきゃだめ、ってことですか?
0307デフォルトの名無しさんNGNG
>>306
そのコードだと、↓といっしょだな。
void foo() {
std::vector<std::string> v;
v.push_back( "美幸...おまえ..." );
}
0308303NGNG
うん、えっと、std::vectorが、
「なにを保持してるのか、どう扱えばいいのか」を知りたかっただけなのです。
そか、307見たいに書けるって事は、
「std::vector::push_backは、引数を基にして、
変換コンストラクタかコピーコンストラクタで新しいインスタンスを作って、
そのインスタンスを保持する」
ってことだよね。

新しいインスタンスを保持するんだから、
元のインスタンスは自分で解放する必要がある、と。

やっと心のもやもやが。ありがとうでした。
0309デフォルトの名無しさんNGNG
「TIME」誌2002年の顔にアラファト議長を! 3
http://live.2ch.net/test/read.cgi/festival/1040234682/

急募!投票ツール作れる方
97式アラファトマシンガンが無効に!  
アラファトの票がリセット!
0310デフォルトの名無しさんNGNG
次のコードがコンパイルできないんですけどなぜ?

#include <iostream>
template <class T>
struct Hoge
{
    friend void func()
    {   std::cout << "フレンド関数なんだけど" <<std::endl; }
};

int main()
{
    func();
}

VC7では、「error: C2065: 'func': 定義されていない識別子です」とおこられます。
#定義してあんだけどなあ〜
0311デフォルトの名無しさんNGNG
>>310
'func' なんてどこにも定義してないだろ。
0312デフォルトの名無しさんNGNG
しかし、310 の friend void func() は、どうやって呼べばいいんだ?
0313310NGNG
>>311 >>312
func() はフレンド関数だから、グローバルスコープのはずですけど
0314デフォルトの名無しさんNGNG
template <class T> って書いてある奴の何がグローバルスコープなんだ?
0315デフォルトの名無しさんNGNG
template Hoge<int>;
int main()
{
func();
}
かな。ま、func() が何かHoge型の引数をとってくれないと無意味だわな。
0316デフォルトの名無しさんNGNG
ということで310はtemplateのインスタンス化について小一時間勉強すること。
0317デフォルトの名無しさんNGNG
#include <iostream>
template <class T>
struct Hoge
{
friend void func<T>()
};

template<class T> void func()
{ std::cout << "フレンド関数なんだけど" <<std::endl; }

こうするはず
0318310NGNG
>>314
template <class T> はHoge に付いているんで、メンバじゃない func() には関係ないと思うけど。

>>315、>>316
動きました。でもなぜ?
func() は普通の関数じゃないの? テンプレートじゃない普通の関数をインスタンス化?
0319デフォルトの名無しさんNGNG
> テンプレートじゃない普通の関数

どうしてそう思うのか訊きたいのだが
0320316NGNG
だから規格書嫁って。
14.5.3
-5- When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template.
0321310NGNG
>>319
フレンド関数が func() が テンプレート Hoge のメンバじゃない、っていうのは正しいですよね。
Hoge のtemplate <class T> は、クラスそのものとメンバに対してしか影響せず、パラメータに依存しているわけでもない func() とはまったく関係ないはず。
func() 自体も関数テンプレートとして定義されているわけじゃない。

だから普通の関数だと思うんだけど。
0322310NGNG
>> 316
へえ、普通の関数でも、個別にインスタンス化されるんだ。
勉強になりました。
でも、ということは、インスタンス化されるごとに同じ定義が再生産されることになるの?
それってやぱくない? 
って、VC7はHoge を複数インスタンス化してもエラーになんないな。大丈夫なのかな?
0323デフォルトの名無しさんNGNG
そのネタくさい物言いなんとかしてください。それにこれは
どっちかというと相談室の方でやる質問なのでは?
0324310NGNG
>>323
>そのネタくさい物言いなんとかしてください。
それは正直、すまんかった。きおつけるよ
>それにこれはどっちかというと相談室の方でやる質問なのでは?
template がらみだから、こっちに投げたけど、こんどからはそうするよ。
0325デフォルトの名無しさんNGNG
タイトルは s/template/generics/ のほうがよかったかもね
0326デフォルトの名無しさんNGNG
関数テンプレートの関数のアドレスって取ることができないの?

template <typename T>
class Hoge {
T i;
public:
Hoge(T t) : i(t) {}
friend void func<>(Hoge<T>&);
};

template <typename T>
void func(Hoge<T>& t)
{
std::cout << "フレンド関数なんだけど" << std::endl;
std::cout << t.i << std::endl;
std::cout << reinterpret_cast<long>(&func) << std::endl;
}

int main()
{
Hoge<int> h(123);
Hoge<int> i(456);
func(h);
func(i);
}
0327デフォルトの名無しさんNGNG
>>326
質問内容と貼り付けるソースを対応させてくれ。
ソースがいろんな(たぶん余計な)要素を含みすぎて
何を答えて欲しいのかがイマイチつかめん。

そのソースでエラーになるんだったら、&func<T>かなー?
0328デフォルトの名無しさんNGNG
>>327
スマソ。いらない要素を除いて短くしました。まだエラーが出ます。
コンパイラはgcc3.2.1(MinGW)です。

template <typename T>
class Hoge {
friend void func<>(Hoge<T>&);
};

template <typename T>
void func(Hoge<T>& t)
{
std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー
}

int main()
{
Hoge<int> h;
Hoge<int> i;
func(h);
func(i);
}
0329デフォルトの名無しさんNGNG
さらに短くしました。friend宣言もクラス宣言も取ってしまいました。

template <typename T>
void func(T t)
{
std::cout << t << std::endl;
std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー
}

int main()
{
func<int>(1);
}
0330デフォルトの名無しさんNGNG
329です。自己解決しました。
テンプレート関数は、コンパイラから関数のオーバーロードと解釈されるようです。
従って、関数名を正しくキャストする事によりうまくコンパイルできました。

template <typename T>
void func(T t)
{
std::cout << t << std::endl;
std::cout << reinterpret_cast<long>(static_cast<void (*)(T)>(func)) << std::endl; //うまく行く
}

int main()
{
func<int>(1);
func<double>(1);
func<int>(2);
}
0331デフォルトの名無しさんNGNG
んーでも少し問題が。gcc3.2.1(MinGW)では通るものの、Borland-C++5.6.2では

エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<int>(int) )
エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<double>(double) )

と言われてしまいました。Borland-C++が糞なのか、それとも私が何か間違っているのか?
0332デフォルトの名無しさんNGNG
Modern C++ Design を読んで疑問に思ったので質問します
8章のオブジェクトファクトリのRegisterコールバック関数の登録についてです。
ある具象クラスLine(: public Shape)のソースにおいて
const bool registered = ShapeFactory::Instance().Register( LINE, CreateLine );
としてシングルトンのファクトリに登録していますが、
これはファクトリがシングルトンの場合にしかつかえないと思うのです。
動的にファクトリを生成・利用する場合には、具象クラスの情報を一ヶ所にまとめた物がどこかに必ず必要になると思うのですが、
この認識は正しいでしょうか?
シングルトンではなく、ファクトリになんの変更も無しに新たな具象クラスを追加する方法があるのでしょうか?
0333デフォルトの名無しさんNGNG
VC.NETのSTLへの対応ってどんなもんなんですか?
VC6.0と同じ程度なんですか?
sort(v.begin(),v.end(),mem_fun_ref(&hoge::hoge)); ←こんなの通るの?
0334デフォルトの名無しさんNGNG
>>332
Factoryクラスのstaticメンバに情報を持つか、FactoryのFactoryに
情報をまとめるようにして、Factoryの生成をライブラリ側で管理するか、
フリー関数のオーバーロードで頑張るかすれば、一応何とか出来るのではないかと。

しかし、ファクトリがSingletonでないことが必要な場合なら、
各々のファクトリが勝手に情報共有してしまったらむしろ
困ると思うのだけど、具体的にどういう場合を想定してるん?

>>333
> mem_fun_ref(&hoge::hoge)
いやコンストラクタをmem_funに渡せる実装はなかなか少ないだろう。

men_fun1_refにしないでも大丈夫になってるか?という意味なら、VC.NET 2002 ならOK。
0335デフォルトの名無しさんNGNG
>>334
すいません、編集ミスです。<コンストラクタ
しかも、ペーストする場所を思いっきり間違えてました。
質問したいのは、これ(↓)でした。
find_if(v.begin(),v.end(),bind2nd(mem_fun_ref(&Hoge::hoge),HogeObject));

手元にg++用に書かれたコード(STL多用)があり、
これにGUI部分を実装しなければならないのですが、
VC6までは、STLがまともに動かないという話を聞いたことがあるので、
VC.NETではどうなってるのかなと思って質問しました。
やっぱり、BCB6の方が良いでしょうか?
0336332NGNG
>>334
疑問に思っていたのは以下の2点でした
・「シングルトン」及び「staticメンバに情報を登録」ではプログラムロード時からメモリに存在する。
・ファクトリ側では実行するまでどんな具象クラスが登録されるかを知らない形にし、各具象クラスのcppファイルで登録させる。

プログラムの流れでたまにしか出てこない、いろんな種類のファクトリをはじめからメモリに確保するのが嫌だったのです。
でも実行時に登録するには、
・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
・どこかにリストアップしておく。
のどちらかしか無いように思います。
用語が滅茶苦茶だと思いますがすいません。
0337sageNGNG
>・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
グローバルはおかしいかな。
cppファイルの頭の部分に書く
const bool registered = Singleton::Register(objType,CreateCallback);
な感じのやつのことです。
0338デフォルトの名無しさんNGNG
ファクトリの百や二百、メモリを使用してるうちに入らんと思える私は幸せなのでしょうか。
0339332NGNG
私もです。しかもせいぜい10個くらい。
0340デフォルトの名無しさんNGNG
std::mem_fun_refってどういう時に使う?
std::mem_funは、仮想関数を呼び出す時に便利だが、std::mem_fun_refだと
クラスへのポインタではなく実体を渡さないといけないので、例えば

class A;
class B : public A;

のようになっているとして、

std::vector<A*> にはBへのポインタも格納できるが、std::vector<A>にBを
格納しようとすると未定義の動作となる。ポインタならばstd::mem_funで
呼び出せる。std::mem_fun_refは実体を渡さなければならないが、vector
に両方は格納できない。

だから、std::for_each()などで、std::mem_fun_refを使う状況というのがどう
いう場合なのか知りたい。
0341デフォルトの名無しさんNGNG
>>340
Aが派生して使うような型じゃない場合。
0342デフォルトの名無しさんNGNG
>>341
なるほど、こんな場合か。単純と言えば単純だな。

class A {
int j;
public:
void print(int i) {
std::cout << i + j << std::endl;
}
A(int k) : j(k) {}
};

int main()
{
std::vector<A> a;

a.push_back(A(1));
a.push_back(A(2));
a.push_back(A(3));

std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::print), 1));
}
0343デフォルトの名無しさんNGNG
boost::anyと、std::mem_fun_refを使って仮想関数を呼び出そうとしたが
なかなかうまく行かない。

int main()
{
std::vector<boost::any> a;

a.push_back(A());
a.push_back(B());

std::for_each(a.begin(), a.end(), std::bind2nd(std::bind1st(std::mem_fun_ref(&A::print), boost::any_cast<A&>(this)), 1)); // だめ
}
0344デフォルトの名無しさんNGNG
どうしてany_castに失敗するのでしょうか?

struct A {
void print() {
std::cout << "A" << std::endl;
}
};
int main()
{
std::vector<boost::any> a;

a.push_back(A());
a.push_back(A());

std::vector<boost::any>::iterator pos = a.begin();
try {
for (; pos != a.end(); ++pos)
boost::any_cast<A>(a).print();
}
catch (boost::bad_any_cast& e) {
std::cerr << e.what() << std::endl;
}
}
0345デフォルトの名無しさんNGNG
>>343
試さずに書いてるが、
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );

>>344
boost::any_cast<A>(*pos).print();
じゃねーの?
0346345NGNG
というか、今のバージョンのany_castって継承関係の把握できたっけ。
0347デフォルトの名無しさんNGNG
Lokiのインストール法、誰か教えて。
英語読めん。
それと、iostreamをインストールすると、コンパイラ付属のは使えなくなるんか。
それはそれで不安だ。教えてくれ。
0348デフォルトの名無しさんNGNG
>>347
DLして解凍して適当なフォルダに入れてインクルードパス通すだけ
というかあれくらいの長さのreadmeくらい読みなよ…

後環境も何も書いてないからこれ以上は無理
0349デフォルトの名無しさんNGNG
Lindows
0350デフォルトの名無しさんNGNG
>>345
ありがとうございます!

boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
は通りませんでしたが、

boost::any_cast<A>(*pos).print();
は無事通りました。

boost::any_castは依存関係の把握はできないかもしれませんので、ポリモルフィズム
には使わないようにします。
0351デフォルトの名無しさんNGNG
ところで C++ Templates [ http://www.josuttis.com/tmplbook/tmplbook.html ;] は既出なのか?
■ このスレッドは過去ログ倉庫に格納されています