【C++】template 統合スレ -- Part5

このエントリーをはてなブックマークに追加
928925:04/11/17 23:22:49
>>927
どーも。
期待通り?VC7.1でもエラーになってくれました。
(template argはfriend指定できないみたい)
class Enemy
{
friend class Friend;//secretに必要

template <class T,class L>struct Connection :public L
{
friend class Friend;//testに必要 ->VC7.1はこっちだけでもOKだった...orz
929デフォルトの名無しさん:04/11/18 03:39:17
C++Primer第3版日本語版P865〜866
クラステンプレートにおけるfriend宣言を見ると、
テンプレート・パラメータはfriendクラスそのものには使えないが、friendクラス
のテンプレート・パラメータの方を指定する事ができる。



template <typename T>
class Foo {
//いろいろ
};

template <typename T>
class A {
 friend class Foo<T>;
};
930デフォルトの名無しさん:04/11/18 04:15:21
>>928
そこでboostですよ。
#include <boost/mpl/identity.hpp>
template <class T>struct Connection
{
typedef typename T::type X;
friend X;
private:
static void test()
{std::cout << typeid(X).name() << ":" << typeid(Connection).name()<< std::endl;}
};

struct Friend :public Connection< boost::mpl::identity<Friend> >
{
using Connection< boost::mpl::identity<Friend> >::test;
};
931925=928:04/11/18 09:30:32
>>929,930
ありがとうございました。関数の方はVC7.1とGCC3.4.3でOKでした。
class Friend_Tag;
template <class T,class L>struct Connection;
template <typename T>class Friend;
class Enemy
{
friend class Friend<Friend_Tag>;//GCCの場合必須
static void secret(){ std::cout << "secret!!" << std::endl; }
static const int secret_data = 1000000;
};
template <class T,class L>struct Connection :public L
{
/*C++Primer第3版日本語版P865〜866
クラステンプレートにおけるfriend宣言を見ると、
テンプレート・パラメータはfriendクラスそのものには使えないが、friendクラス
のテンプレート・パラメータの方を指定する事ができる。*/
friend class Friend<T>;
typedef Connection<T,L> connect_type;
private:static void test()
{std::cout << typeid(T).name() << ":" << typeid(Connection).name()<< std::endl;}
static const int test_data = 100000;
};
class Friend_Tag{};//friendクラスのテンプレート・パラメータの方を指定
template <typename T=Friend_Tag>class Friend :public Connection<T,Enemy>
{public:
using connect_type::test; //friend経由でusingする
using connect_type::secret;//friend経由でusingする
//using connect_type::test_data; //friend経由でusingする GCC3.4.3(OK) VC7.1(NG)
//using connect_type::secret_data;//friend経由でusingする GCC3.4.3(OK) VC7.1(NG)
};
932デフォルトの名無しさん:04/11/18 11:09:35
>>931
君にはC++Templatesをお勧めしよう。
大きな声では言えないが、CHMやPDFはよく探せばどこにでも落ちている。
俺は画面で見るのが嫌なのでAMAZONで買ったが。
しかしこんな名著がなぜ日本語訳化されないのか不思議。
933デフォルトの名無しさん:04/11/18 11:45:59
これ読んだ人はいますか?
C++ Template Metaprogramming
: Concepts, Tools, and Techniques from Boost and Beyond
http://www.amazon.com/exec/obidos/tg/detail/-/0321227255/
934デフォルトの名無しさん:04/11/18 11:56:45
>>933
まだだけど内容が偏ってそうなタイトルだな。
935デフォルトの名無しさん:04/11/18 12:00:47
936936:04/11/18 14:05:19

std::string a(){ return ""; }
int b(){ return 0; }

template< void (*pf)() >
struct A
{ static const int id=0; };

template< class R, R (*pf)() >
struct A<pf>
{ static const int id=1; };


int main()
{
 std::cout << A< &a >::id << std::endl;
 std::cout << A< &b >::id << std::endl;
 return 0;
}
error C2764: 'R' : テンプレート パラメータは部分的特殊化 'A<pf>' では使用されません。
main内をいじくらずにコンパイルをとおすにはどうしたらいいですか?
937デフォルトの名無しさん:04/11/18 14:13:01
>>936のコードをBCCでやろうとしたらできちゃった。
これじゃ俺には答えられん。OTL
938デフォルトの名無しさん:04/11/18 16:44:50
>>936
お前がやりたいのはこれか?

template <typename FP>
struct A;

template <typename R>
struct A<R (*)()>
{enum{id = 0};};

template <>
struct A<void (*)()>
{enum{id = 1};};
939デフォルトの名無しさん:04/11/18 17:21:54
>>938
936さんは外部リンケージのある関数ポインタをテンプレートの
非型パラメータに取りたいんでしょう.

>>936
ですか?
そのコードはprimary templateとその特殊化で非型パラメータの型が異っていて
(void (*)()とR (*)()),そういう特殊化は許されないです.
なのでmain関数をいじらずにそれを通すのは無理と思います.
見たところ,関数ポインタからその戻り値がvoidかどうかを判別する静的整数値が
欲しいと見受けられますが,その解釈で良いですか?
940デフォルトの名無しさん:04/11/19 18:49:20
STLPortってシリアライズ対応してるんですか?
みあたらないのですが・・・・・
941936:04/11/19 19:40:16
>>939 やりたいことは関数ポインタを非型パラメータとして渡し戻り値の型をresult_tとかで取得できるようにしたいです
以下のソースでとりあえず関数ポインタを単独で渡すことに成功して、いけるかとおもったのですが全部null_tですた
試しに非型パラメータ経由で呼び出したらおちますたorz
template<class T>struct aaa{};
int a(){return 0;}
std::string b(){return "";}
aaa<int> c() { return aaa<int>(); }
struct null_t{};
template<void *p,class R=null_t>struct A
{
 typedef null_t result_t;
 static const id = 0;
};
template<class R, R (*const pf)()>struct A< pf, R >
{
 typedef R result_t;
 static const id = 1;
 test(){ (*pf)(); }
};

int main()
{
 std::cout << typeid(A<&a>::result_t).name() << " " << A<&a>::id << std::endl;
 std::cout << typeid(A<&b>::result_t).name() << " " << A<&b>::id << std::endl;
 std::cout << typeid(A<&c>::result_t).name() << " " << A<&c>::id << std::endl;
 A<&a> a; A<&b> b; A<&c> c;
 return 0;
}
942デフォルトの名無しさん:04/11/19 20:31:48
>>941
それは無理。
typeofが使える環境ならいいけど。
943デフォルトの名無しさん:04/11/20 01:24:25
gcc3.2 3.3 3.4 以降 の libstdc++ と、STLportでは、どっち使ってます?
gcc も version 3から、c++ 対応が強化されてますし。

http://boost.sourceforge.net/regression-logs/
みても、stlport は、いらないかと。
VC がないんだけど、前はあったような気がするのだが。

VC7.1 の場合も標準準拠具合は進んでるし、STLport いらないかも?

でもSTLport のほうが速いのかな。
944デフォルトの名無しさん:04/11/20 01:31:21
STLPortのデバッグモードがいいよ
945デフォルトの名無しさん:04/11/20 01:57:31
>941
942さんの言うようにその要求はまさにtypeofの機能なので厳しいでしょう.
戻り値がvoidかそうでないか等のように,オブジェクトのある程度の種別を
識別するコンパイル時定数を得ることなら以下の手法で出来ますが・・・.

#include <iostream>
struct yes_t{ };
struct no_t{ yes_t padding[256]; };
template<class T> no_t is_void_ret(T (*)());
yes_t is_void_ret(void (*)());
#define IS_VOID_RET(pf) (sizeof(is_void_ret(pf)) == sizeof(yes_t))
void f(){ };
int g(){ return 0; }
int main()
{
std::cout << IS_VOID_RET(&f) << std::endl;
std::cout << IS_VOID_RET(&g) << std::endl;
}

ちなみにこの手法の究極形が,既存のC++の文法のみでtypeofを実現するってヤツなんですけどね.
946デフォルトの名無しさん:04/11/20 15:53:55
boost1.32.0 2004-11-19 18:47
キタ━━━━(゚∀゚)━━━━!!
ttp://sourceforge.net/project/showfiles.php?group_id=7586
947デフォルトの名無しさん:04/11/20 16:46:57
boost1.32.0キタ━━━━(゚∀゚)━━━━!!
948Booster達の午後^H^H週末:04/11/20 16:51:38
boost1.32.0やっとキタ━━━━(゚∀゚)━━━━!!
949デフォルトの名無しさん:04/11/20 16:54:28
おまえら気づくのおせーよw
950デフォルトの名無しさん:04/11/20 17:03:38
タグは打たれないのかい?
951デフォルトの名無しさん:04/11/20 20:53:41
すみません、質問があります。
boostのファンクタを使ってみようと思っているのですが、
脳がこんがらがってきました。

boost::shared_ptr< hoge > pointer;
というポインタと、
std::list< boost::weak_ptr< hoge > > container;
というコンテナがあり、
コンテナの中からremove_if()でpointerと同じ値を削除したいのです。

ところが、コンテナの中身がweak_ptrなので、一度lock()しないといけません。
こういう場合、どういうファンクタを書けばいいのでしょうか?
出来ればlambdaを使わず(怖すぎ)、bindやmem_fnだけで書く方法を
教えていただけないでしょうか。
952951:04/11/22 03:16:59
誰か答えろよ。
953デフォルトの名無しさん:04/11/22 06:38:53
頭がこんがらがるようなことはやらないが吉。
954デフォルトの名無しさん:04/11/22 14:56:58
955デフォルトの名無しさん:04/11/22 14:58:17
誰だよ昨晩から上げ荒らしをしているばかは。一応通報したからね。
956デフォルトの名無しさん:04/11/22 16:40:20
>>952
解っているがおまえの態度が気に入らない。
957デフォルトの名無しさん:04/11/22 17:45:39
>>955
どうやらRuby信者の荒らしみたい
958デフォルトの名無しさん:04/11/23 14:01:29
boost lambda で再帰ってどう書けばいいのかな?
959デフォルトの名無しさん:04/11/23 14:53:07
>>958
具体例プリーズ
960デフォルトの名無しさん:04/11/23 18:14:16
>>958
試してないけどboost::functionも使ってこんな感じで行けない?
function<int (int)> f= ret<int>(if_(_1==0)[1].else_[_1*f(_1-1)]);
cout<< f(5)<< endl;
961デフォルトの名無しさん:04/11/23 18:22:51
boostの悪い使い方の典型だな
962958:04/11/24 17:50:36
>>960
function<int (int)> f= ret<int>
(if_then_else_return(_1==1,1,_1*f(_1-1)));
とかもやってみたけど駄目みたい。(再帰はムリなのかもしれぬ...


963デフォルトの名無しさん:04/11/24 17:55:29
ここまでしてlambda使いたいか?て思う
半年ぐらいC++から離れたら読めなくならない?
964デフォルトの名無しさん:04/11/24 18:59:33
>>962
fの呼び出しはbindで包まないとだめだと思うが。
俺の環境ではif_then_elseが使えないから、
function<int (int)> f= bind<int>(var(f), _1);
で、スタックオーバーフローを確認した。
965デフォルトの名無しさん:04/11/24 20:37:30
main() {
 int (*tarai)();
 tarai = lambda(x,y,z) {
  if (x <= y) return y;
  else return tarai(
   tarai(x - 1, y, z),
   tarai(y - 1, z, x),
   tarai(z - 1, x, y));
  };

 (lambda(x,y,z){ printf("tarai => %d\n",tarai(x,y,z)); })(12,6,0);
}

これをboostで書き直すとどうなるの?
966デフォルトの名無しさん:04/11/25 02:07:57
>>965
#include <cstdio>
#include "boost/function.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/if.hpp"
#include "boost/bind/protect.hpp"
#include "boost/ref.hpp"

int main()
{
  boost::function<int (int,int,int)> tarai;
  using namespace boost::lambda;
  using boost::protect;
  using boost::ref;
  tarai =
    if_then_else_return((_1 <= _2)
      , ret<int>(_2)
      , bind(ref(tarai)
        , (protect(bind(ref(tarai), _1 - 1, _2, _3)))(_1,_2,_3)
        , (protect(bind(ref(tarai), _2 - 1, _3, _1)))(_1,_2,_3)
        , (protect(bind(ref(tarai), _3 - 1, _1, _2)))(_1,_2,_3)
        )
      );

  std::printf("tarai => %d\n", tarai(12,6,0));
}
967デフォルトの名無しさん:04/11/25 05:15:37
マジでboostからlambdaはずして欲しい。
968デフォルトの名無しさん:04/11/25 05:19:26
>>967
使わなければいいのでは?
969デフォルトの名無しさん:04/11/25 05:20:42
俺が使わなくても他のやつが使うじゃん。
俺そんなの読むのヤだよ。
って実際lambda使ってるやつ見たことないけど。
970デフォルトの名無しさん:04/11/25 05:29:16
勝手だなぁw
971デフォルトの名無しさん:04/11/25 05:36:02
lambda を馬鹿みたいに多用する奴がアホなだけだからなま暖かく見守っとけば?
972デフォルトの名無しさん:04/11/25 05:59:39
boost自体がお遊びでしょ
973デフォルトの名無しさん:04/11/25 06:03:47
boost見てると
「でっきる〜かな、でっきる〜かな♪」
と聞こえてくるんですが。
974デフォルトの名無しさん:04/11/25 06:08:04
>>973
「さてさて、ふふ〜ん」ってか
975デフォルトの名無しさん:04/11/25 08:11:21
ほんとうに聞こえてくるなら病院に行ったほうがいいかと。
976デフォルトの名無しさん:04/11/25 08:19:19
C++にlambdaがないのがいけないんだよ。
Perlにすらあるのに。
977デフォルトの名無しさん
lambdaは予約語だからな。使わないようにしておかないと。