【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 あたりに。
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引き篭もり
NGNG0265デフォルトの名無しさん
NGNG{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < std::string("abc";) //(2) OK
}
のように、sts::stringの一時変数を作って渡してやらないと、テンプレート関数
の方を呼んでくれない。この当たりがテンプレートの限界なのか。
0266デフォルトの名無しさん
NGNGexplicit dd(const typename dd<T>::char_type& a){
static_cast<T&>(*this) = a;
}
これって一体どこに代入しているの?どうみても自分自身に代入しているように
しか見えないのだが・・・・・どんな意味があるのだろう。
0267デフォルトの名無しさん
NGNGMore Effective C++のp.16、l2に実際のプログラムでは、このようなクラスはテンプレートになるのだが、
とあります。具体的にはどのように書けばいいのでしょうか?
0268デフォルトの名無しさん
NGNGなんか激しく気持ち悪い書き方だなぁ。
*(static_cast<T*>(this)) = a;
あるいはすなおに
T::operator=(a);
と書いたほうがわかりやすくないかい?
0269デフォルトの名無しさん
NGNGたんに、要素の型を int きめうちじゃなくてテンプレート引数で
指定できるようにすべきだ、ってことじゃないの?
0270デフォルトの名無しさん
NGNGというか、素直にこうだろ〜
explicit dd(const typename dd<T>::char_type& a) : T(a) { }
0271デフォルトの名無しさん
NGNG>>268>>270 やっはりそうですよね。分かりやすく書くことを心がけるようにします。
0272デフォルトの名無しさん
NGNGstatic_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ちょっと違う。A::A(); と書くと、コンストラクタを呼び出したことにはならない。
単にAの一時変数が作成されてすぐに破棄されるだけ。
明示的にコンストラクタを呼び出すには、コンストラクタ初期化子を使う
しかない。
0274デフォルトの名無しさん
NGNGこれ、: m_str(c) の間違いではなくて?
こういう書き方あるの?
0275デフォルトの名無しさん
NGNGなるほど!
>>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デフォルトの名無しさん
NGNGthis->A::A();
これならOKなのでは?
0277デフォルトの名無しさん
NGNGエラーっしょ。
0278デフォルトの名無しさん
NGNGできるよ。
#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コンパイラは何を使った?Borland-C++5.6.2及びgcc3.2(MinGW)は
エラーが出て通らないけど。
0281デフォルトの名無しさん
NGNGBCC5.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
というエラーです。
0283デフォルトの名無しさん
NGNG俺も調べてみるが、確かコンストラクタからコンストラクタを呼び出すには、
初期化リストしか方法がなかったように記憶しているが・・・・どうだったっけな
0284デフォルトの名無しさん
NGNGどっかのメーリングリストではVC固有の機能だと言われてたな。
>>283
ちょっと話は変わるけど、こんなのどう?
static_cast<T*>(this)->~T();
new(this)T(param);
newで例外が起きるとヤバイが。
0285デフォルトの名無しさん
NGNGnewの配置構文ですね。この場合、デストラクタは自分で呼び出してやらないと
いけないですね。
0286デフォルトの名無しさん
NGNGだから直前に呼んでるみたいだが
0287デフォルトの名無しさん
NGNGそうか?
この場合、Tは(*this) の型の基底クラスだろ
この型のデストラクタがデフォで ~T() 呼ぶから
大丈夫だと思うんだが、どうよ
>>286
ちょっと、目の付け所がいまいち
0288デフォルトの名無しさん
NGNGそっか。そう言われればそうだな。途中でリコンストラクトした事にはコンパイラ
は気づいてないだろうからね。
0289デフォルトの名無しさん
NGNG0290デフォルトの名無しさん
NGNG× 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実行結果が次のようになったのだが、大丈夫だろうか?
Base::Base()
エロ::~エロ() //←これヤバくない?
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()
0293デフォルトの名無しさん
NGNG// ぜんぜん違うぞ、こうだ
#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);
}
0294293
NGNGテンプレート使う必然性無く、まったくレス違いなネタのような……
0295デフォルトの名無しさん
NGNGををををぉぉぉぉなんとトリッキーな。
Fooのインスタンスが先に生成されるのが意外だったけど、これは使えそうだね。
0296291
NGNGやばいです。
つーか、うち(VC7)ではこうなりました。
仮想関数テーブルの取り出し方が違うのでしょうか?
Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()
>>293
飛び入りな者でスミマセン。
0297デフォルトの名無しさん
NGNG>>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デフォルトの名無しさん
NGNGEro(int) {
this->Base::~Base(); // thisから呼び出すようにした
new(this) Ero();
std::cout << "エロ::エロ(int)" << std::endl;
}
Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
コンパイラによって実行結果がバラバラですね(^_^;)。
0299デフォルトの名無しさん
NGNG出じゃブーが多いなあ。
0300デフォルトの名無しさん
NGNG0301デフォルトの名無しさん
NGNG>コンパイラによって実行結果がバラバラですね(^_^;)。
データレイアウトの違いが原因かも(根拠なし)
0302デフォルトの名無しさん
NGNG300getしてるよ。
2〜3年前に似たようなこと頑張って考えてた時期あった。
基本型とユザ定義型の区別とか。
コンパイル時のじゃなくて実行時に区別するやつ。
ただしおれは目的があくまでパズルだった。
実用にしようと思ってたらなんか結果出てたかな...?
0303デフォルトの名無しさん
NGNGしないですよね?
void foo() {
std::vector<std::string> v;
v.push_back( *(new std::string("お兄ちゃん♥") );
}
0304デフォルトの名無しさん
NGNG{
for(std::vector<std::string>::iterator it=v.begin(); it!=v.end, ++it)
delete &(*it);
v.clear();
}
とかやらないと駄目なんじゃない?
0305デフォルトの名無しさん
NGNG(*it)はnewで作成したstringを
コピーコンストラクタでコピーした物だからダメだと思うが。
0306303
NGNGえっと、つまり、
void foo() {
string* p;
std::vector<std::string> v;
v.push_back( *(p = new std::string("美幸...おまえ...") );
delete p;
}
ってやらなきゃだめ、ってことですか?
0307デフォルトの名無しさん
NGNGそのコードだと、↓といっしょだな。
void foo() {
std::vector<std::string> v;
v.push_back( "美幸...おまえ..." );
}
0308303
NGNG「なにを保持してるのか、どう扱えばいいのか」を知りたかっただけなのです。
そか、307見たいに書けるって事は、
「std::vector::push_backは、引数を基にして、
変換コンストラクタかコピーコンストラクタで新しいインスタンスを作って、
そのインスタンスを保持する」
ってことだよね。
新しいインスタンスを保持するんだから、
元のインスタンスは自分で解放する必要がある、と。
やっと心のもやもやが。ありがとうでした。
0309デフォルトの名無しさん
NGNGhttp://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'func' なんてどこにも定義してないだろ。
0312デフォルトの名無しさん
NGNG0314デフォルトの名無しさん
NGNG0315デフォルトの名無しさん
NGNGint main()
{
func();
}
かな。ま、func() が何かHoge型の引数をとってくれないと無意味だわな。
0316デフォルトの名無しさん
NGNG0317デフォルトの名無しさん
NGNGtemplate <class T>
struct Hoge
{
friend void func<T>()
};
template<class T> void func()
{ std::cout << "フレンド関数なんだけど" <<std::endl; }
こうするはず
0318310
NGNGtemplate <class T> はHoge に付いているんで、メンバじゃない func() には関係ないと思うけど。
>>315、>>316
動きました。でもなぜ?
func() は普通の関数じゃないの? テンプレートじゃない普通の関数をインスタンス化?
0319デフォルトの名無しさん
NGNGどうしてそう思うのか訊きたいのだが
0320316
NGNG14.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.
0321310
NGNGフレンド関数が func() が テンプレート Hoge のメンバじゃない、っていうのは正しいですよね。
Hoge のtemplate <class T> は、クラスそのものとメンバに対してしか影響せず、パラメータに依存しているわけでもない func() とはまったく関係ないはず。
func() 自体も関数テンプレートとして定義されているわけじゃない。
だから普通の関数だと思うんだけど。
0322310
NGNGへえ、普通の関数でも、個別にインスタンス化されるんだ。
勉強になりました。
でも、ということは、インスタンス化されるごとに同じ定義が再生産されることになるの?
それってやぱくない?
って、VC7はHoge を複数インスタンス化してもエラーになんないな。大丈夫なのかな?
0323デフォルトの名無しさん
NGNGどっちかというと相談室の方でやる質問なのでは?
0324310
NGNG>そのネタくさい物言いなんとかしてください。
それは正直、すまんかった。きおつけるよ
>それにこれはどっちかというと相談室の方でやる質問なのでは?
template がらみだから、こっちに投げたけど、こんどからはそうするよ。
0325デフォルトの名無しさん
NGNG0326デフォルトの名無しさん
NGNGtemplate <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質問内容と貼り付けるソースを対応させてくれ。
ソースがいろんな(たぶん余計な)要素を含みすぎて
何を答えて欲しいのかがイマイチつかめん。
そのソースでエラーになるんだったら、&func<T>かなー?
0328デフォルトの名無しさん
NGNGスマソ。いらない要素を除いて短くしました。まだエラーが出ます。
コンパイラは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デフォルトの名無しさん
NGNGtemplate <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テンプレート関数は、コンパイラから関数のオーバーロードと解釈されるようです。
従って、関数名を正しくキャストする事によりうまくコンパイルできました。
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エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<int>(int) )
エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<double>(double) )
と言われてしまいました。Borland-C++が糞なのか、それとも私が何か間違っているのか?
0332デフォルトの名無しさん
NGNG8章のオブジェクトファクトリのRegisterコールバック関数の登録についてです。
ある具象クラスLine(: public Shape)のソースにおいて
const bool registered = ShapeFactory::Instance().Register( LINE, CreateLine );
としてシングルトンのファクトリに登録していますが、
これはファクトリがシングルトンの場合にしかつかえないと思うのです。
動的にファクトリを生成・利用する場合には、具象クラスの情報を一ヶ所にまとめた物がどこかに必ず必要になると思うのですが、
この認識は正しいでしょうか?
シングルトンではなく、ファクトリになんの変更も無しに新たな具象クラスを追加する方法があるのでしょうか?
0333デフォルトの名無しさん
NGNGVC6.0と同じ程度なんですか?
sort(v.begin(),v.end(),mem_fun_ref(&hoge::hoge)); ←こんなの通るの?
0334デフォルトの名無しさん
NGNGFactoryクラスのstaticメンバに情報を持つか、FactoryのFactoryに
情報をまとめるようにして、Factoryの生成をライブラリ側で管理するか、
フリー関数のオーバーロードで頑張るかすれば、一応何とか出来るのではないかと。
しかし、ファクトリがSingletonでないことが必要な場合なら、
各々のファクトリが勝手に情報共有してしまったらむしろ
困ると思うのだけど、具体的にどういう場合を想定してるん?
>>333
> mem_fun_ref(&hoge::hoge)
いやコンストラクタをmem_funに渡せる実装はなかなか少ないだろう。
men_fun1_refにしないでも大丈夫になってるか?という意味なら、VC.NET 2002 ならOK。
0335デフォルトの名無しさん
NGNGすいません、編集ミスです。<コンストラクタ
しかも、ペーストする場所を思いっきり間違えてました。
質問したいのは、これ(↓)でした。
find_if(v.begin(),v.end(),bind2nd(mem_fun_ref(&Hoge::hoge),HogeObject));
手元にg++用に書かれたコード(STL多用)があり、
これにGUI部分を実装しなければならないのですが、
VC6までは、STLがまともに動かないという話を聞いたことがあるので、
VC.NETではどうなってるのかなと思って質問しました。
やっぱり、BCB6の方が良いでしょうか?
0336332
NGNG疑問に思っていたのは以下の2点でした
・「シングルトン」及び「staticメンバに情報を登録」ではプログラムロード時からメモリに存在する。
・ファクトリ側では実行するまでどんな具象クラスが登録されるかを知らない形にし、各具象クラスのcppファイルで登録させる。
プログラムの流れでたまにしか出てこない、いろんな種類のファクトリをはじめからメモリに確保するのが嫌だったのです。
でも実行時に登録するには、
・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
・どこかにリストアップしておく。
のどちらかしか無いように思います。
用語が滅茶苦茶だと思いますがすいません。
0337sage
NGNGグローバルはおかしいかな。
cppファイルの頭の部分に書く
const bool registered = Singleton::Register(objType,CreateCallback);
な感じのやつのことです。
0338デフォルトの名無しさん
NGNG0339332
NGNG0340デフォルトの名無しさん
NGNGstd::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デフォルトの名無しさん
NGNGAが派生して使うような型じゃない場合。
0342デフォルトの名無しさん
NGNGなるほど、こんな場合か。単純と言えば単純だな。
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なかなかうまく行かない。
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デフォルトの名無しさん
NGNGstruct 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試さずに書いてるが、
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
>>344
boost::any_cast<A>(*pos).print();
じゃねーの?
0346345
NGNG0347デフォルトの名無しさん
NGNG英語読めん。
それと、iostreamをインストールすると、コンパイラ付属のは使えなくなるんか。
それはそれで不安だ。教えてくれ。
0348デフォルトの名無しさん
NGNGDLして解凍して適当なフォルダに入れてインクルードパス通すだけ
というかあれくらいの長さのreadmeくらい読みなよ…
後環境も何も書いてないからこれ以上は無理
0349デフォルトの名無しさん
NGNG0350デフォルトの名無しさん
NGNGありがとうございます!
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
は通りませんでしたが、
boost::any_cast<A>(*pos).print();
は無事通りました。
boost::any_castは依存関係の把握はできないかもしれませんので、ポリモルフィズム
には使わないようにします。
0351デフォルトの名無しさん
NGNG0352名無しさん@Emacs
NGNGっつーか皆さん boost::any ってどんな時に使ってます?
イチイチ any_cast 噛まさにゃならん上にポリモーフィズム使えないもの
をどんな風に使うのか興味があるのですが・・・
# つまり馬鹿だから使い道が思い付かないわけでして。
struct A { virtual void print() { std::cout << "A" << std::endl; }};
struct B : public A{ virtual void print() { std::cout << "B" << std::endl; }};
int main()
{
std::vector<boost::any> a;
a.push_back(new A());
a.push_back(new B());
std::vector<boost::any>::iterator pos = a.begin();
try {
for (; pos != a.end(); ++pos) boost::any_cast<A*>(*pos)->print();
}
catch (boost::bad_any_cast& e) {
std::cerr << e.what() << std::endl;
}
}
output>
A
boost::bad_any_cast: failed conversion using boost::any_cast
0353デフォルトの名無しさん
NGNGvoid* で汎用パラメータ渡し…とか、union でノードの種類を区別した
木構造…とかのtypesafeなバージョンとしては、とりあえず超高速で
お手軽に書こう、と思ったときには使えるかも。俺は使ったこと無いけど。
using namespace boost;
struct add { add(any l,any r):left(l),right(r){} any left, right; };
struct mul { mul(any l,any r):left(l),right(r){} any left, right; };
double eval_expr( any e )
{
if( e.type() == typeid(add) ) {
add ex = any_cast<add>(e);
return eval_expr( ex.left ) + eval_expr( ex.right );
} else if( e.type() == typeid(mul) ) {
mul ex = any_cast<mul>(e);
return eval_expr( ex.left ) * eval_expr( ex.right );
} else if( e.type() == typeid(double) ) {
return any_cast<double>(e);
} return any_cast<int>(e);
}
int main()
{
any expr = add( add(mul(6,7),2), mul(3,4) );
cout << eval_expr( expr ) << endl;
}
その手の使い方をするにしても、入れられる型に制限をつけた
variantとかの方がマシだしなぁ。
0354デフォルトの名無しさん
NGNGany.hppの中身を見てみると、boost::any_castはキャストしようとする型と、
元のタイプのtypeidを比較して、一致しないとキャストしないようになっている。
だからポリモルフィズムに使えないんだろう。
-- any.hpp (STLpotrt)より
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
std::mem_fun_refと組み合わせていろいろと面白い事をやらせようとしていた
のだが、使えねー。まあだめならだめで昨日から悩み続けていた事が解決
したのでいいのだが。
0355デフォルトの名無しさん
NGNG0356デフォルトの名無しさん
NGNGclass A {
public:
void func(int i) {
std::cout << i << std::endl;
}
};
int main()
{
std::vector<A> a;
a.push_back(A());
a.push_back(A());
std::for_each(a.begin(), a.end(), std::compose1(std::mem_fun_ref(&A::func), 1);
}
0357デフォルトの名無しさん
NGNGわからなくなってきた。
class A {
public:
void func(int i) {
std::cout << i << std::endl;
}
};
int main()
{
std::vector<A> a;
a.push_back(A());
a.push_back(A());
std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::func), 1));
}
0358デフォルトの名無しさん
NGNGわかりますか?コンパイラはgcc3.2.1です。
int main()
{
double ad[] = {0.5, 1.0, 1.5};
std::vector<double> d(ad, ad + 3);
std::transform(d.begin(), d.end(), std::ostream_iterator<double>(std::cout, " "), std::sin);
}
0359デフォルトの名無しさん
NGNG#include <cmath>を#include <math.h>にして、std::sinをsinにすれば通ります。
しかし、ここで当然疑問が沸きます。なぜstd名前空間に包まれているsinが
std::transformに適用できないのか、どうしてもわかりません。何のための
<cmath>なんでしょうか?
■ このスレッドは過去ログ倉庫に格納されています