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

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

レス数が950を超えています。1000を超えると書き込みができなくなります。
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 あたりに。
0894デフォルトの名無しさんNGNG
>>892

>setlocale(LC_ALL,"Japanese");を忘れてました。

ライブラリ側の問題ぽいので
S.str()で回避して使っていこうと思います。

ありがとうございました。
0895デフォルトの名無しさんNGNG
>>893
std::queueのラッパーでいいんじゃねーの。
0896デフォルトの名無しさんNGNG
キュー、っつーかリングバッファだな。
リングバッファを実現するコンテナアダプタはSTLの解説で幾つか見たことあるが、
公開されてるものはない気がするから自分で作ったほうがはやそう。
0897893NGNG
>>895, 896
どっかから参考になりそうなものを探して自作することにします。
ありがとうございました。
0898デフォルトの名無しさんNGNG
FIFOバッファだからdeque使えばいいだけの話じゃないの?
0899 NGNG
stlport_vc6.dll を stlport.dll にリネームして使いたいと思います。
方法がわかる方はいらっしゃいませんか?
いらっしゃいましたら、方法を教えてください。

まさか stlport_vc6.lib をバイナリ・エディット?
0900デフォルトの名無しさんNGNG
G++でwcoutを使うにはどうすればよいのでしょうか?
0901デフォルトの名無しさんNGNG
std::vector<std::string> a;
ってやっちゃだめなの?
0902デフォルトの名無しさんNGNG
>>901
当然良し。
0903デフォルトの名無しさんNGNG
vector<bool>を使ったらだめな理由がわかりません。
つーか便利だよ
vector<char>だと8倍メモリくうし

bool *p=&vec[0];
これができないとなんでだめなんだよー
0904デフォルトの名無しさんNGNG
http://www.agemasukudasai.com/bloom/
0905デフォルトの名無しさんNGNG
>>902
vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
なんかあやしいきもするんですが・・・
0906デフォルトの名無しさんNGNG
>vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
VC6発見

#pragma warning (disable : 4786)
ソースの先頭に置いときなさい
0907デフォルトの名無しさんNGNG
>>906
はーい
0908デフォルトの名無しさんNGNG
>>885
ちょいと遅レスだがたしかSTLは効率のために内部にちょびっと
つねにメモリもってるらしいよ。どっかの過去ログにあるはず。
で、どっかで何かをdefineすればなくなるがパフォーマンス
悪くなる。(ってことなのかな?的外れだったらスマソ)
0909デフォルトの名無しさんNGNG
>>908
そういうのはメモリリークとは言わないけどね。
0910デフォルトの名無しさんNGNG
>>908
メモリプールといいます。そういうのは。
0911デフォルトの名無しさんNGNG
コンテナとかはstlport使ってるんですが、
stlportのiostreamを使う利点はあるのですか?
static-linkだと容量でかくなるし
もしたいした違いがないならコンパイルせずに
標準のiostream使おうと思うので
教えてください
0912デフォルトの名無しさんNGNG
STLportのCVSにWinCVS(or TortoiseCVS)でアクセスできませんか?
0913912NGNG
もちろん、読み取りだけで十分です。
0914デフォルトの名無しさんNGNG
>>900
glibc のバージョンが古いと思われ。
glibc-2.2(だったかな?)以降が入ってる環境を使うべし。
0915デフォルトの名無しさんNGNG
 set<string> coll;
という変数宣言がされている状況で、
 for_each(istream_iterator<string>(cin), istream_iterator<string>(),
      coll.insert);
としたいんだけど、gcc-2.95.3 では
no matching function for call to `for_each (istream_iterator<string>, istream_iterator<string>, {unknown type})'
とエラーになってしまう…
(本当はもっとエラーメッセージが長いけど、適宜省略)

プロ言C++第3版の13.2.3を見ると「テンプレート引数としては…メンバに対す
る多重定義されていないポインタなどが使える」とあって、これからすると、
このset<string>::insertみたいな多重定義されているメンバ関数はテンプレート
引数としては渡せないような気もするんだけど、これって本当?
0916915NGNG
やりたいことは、下記のような関数オブジェクトInserterを作って、
 template<class Collection>class Inserter {
  private:
     Collection *container;
  public:
     Inserter(Collection &c) { container = &c; }

     void operator()(const typename Collection::value_type &v)
     {
         (*container).insert(v);
     }
 };
coll.insert の代わりに Inserter< set<string> >(coll) と書けば
できたけど、なんか納得いかないというか、イマイチGenericじゃない
気がしてる。実際、for_eachを手で展開して
 istream_iterator<string> in(cin);
 while (in != istream_iterator<string>())
     coll.insert(*in++);
とすれば動くだけに、なんかクヤしい。
なんか良い手ないかしら?
0917デフォルトの名無しさんNGNG
std::insert_iterator, std::inserterというのがあるわけだが。
0918デフォルトの名無しさんNGNG
#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
std::set<std::string> sset;
std::copy(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::inserter(sset,sset.begin()));

std::copy(sset.begin(),sset.end(),std::ostream_iterator<std::string>(std::cout,"\n"));

return 0;
}
0919デフォルトの名無しさんNGNG
>>916

std::set<std::string> coll;
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::insert_iterator<std::set<std::string> >(coll, coll.begin()));

std::setに関するstd::insert_iterator()の定義はちょっと面白いようになっている。
c.insert(p, t) を呼び出すわけだが、std::setではinsertのメンバ関数は探索位置を
指定する必要はない。だが互換性のためにヒントとしてパラメータを持っている。
そのためstd::insert_iterator()が使えるのである。
0920デフォルトの名無しさんNGNG
std::back_inserter()は使えない。なぜならstd::setはpush_back()というメンバ関数を
持たないからだ。
0921デフォルトの名無しさんNGNG
>>918-920
ども。それは分かります。
ただ、915-916 で言いたかったのは、この処理は間違いなく
for_eachイディオムで書ける筈だし、実際マクロならFOR_EACH
の形で書けので、templateでだって可能じゃないのか、916で
やったように、insertをハードコードすることなく、(Scheme
なら lambda を使って簡単に書けるわけだから) C++ でもなにか
方法がある筈じゃないのかってことなんでした。
もっとも 915-916を書いた時点では、自分でも何が気に入ら
なかったのかはっきりしてなかったので、うまく書けませんでした。
0922915NGNG
で、915で書いた推測は全く見当はずれでした。

3点大きな間違いがあって、まずそもそも「coll.insert」
っていうのは、C++ の文法上許されない表現なので、
template関数の引数には書けません。(^^;
正しい表現は &set<string>:insert となりますが、
この場合、&set<string>:insert だけでなく coll も
別に渡してやる必要がありました。

それから、この場合、coll.insert を渡している場所は
テンプレート引数ではなく、テンプレート関数の通常の
引数なので、くだんのプロ言C++第3版の13.2.3の記述は
そもそも関係ありませんでした。

最後に、ちゃんと確認してみたところ、使っている処理系
(gcc-2.95.3)だと、多重定義されているメンバ関数を
テンプレート引数として渡すことだって可能でした。
(gccの拡張機能?)
0923デフォルトの名無しさんNGNG
で、922で書いたようにcollも渡す必要があるわけで、
mem_fun_refに習って、次のような関数オブジェクトを定義しました。

template<typename ReturnType, typename Class, typename Arg1Type>
class obj_mem_fun1_t : public unary_function<Arg1Type, ReturnType> {
private:
    Class *object;
    ReturnType (Class::*memfun)(Arg1Type);
public:
    explicit obj_mem_fun1_t(Class &o, ReturnType (Class::*mf)(Arg1Type))
        : object(&o), memfun(mf) {}

    void operator()(Arg1Type a1)
    {
        ((*object).*memfun)(a1);
    }
};

template <typename ReturnType, typename Class, typename Arg1Type>
inline obj_mem_fun1_t<ReturnType, Class, Arg1Type>
obj_mem_fun(Class &object, ReturnType (Class::*mf)(Arg1Type))
{
    return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf);
}
0924915NGNG
これで、
 for_each(
 istream_iterator<string>(cin),
 istream_iterator<string>(),
   obj_mem_fun(coll, &set<string>::insert));
とすればOKかなと思ったんですが、gcc-2.95.35だと
no matching function for call to `obj_mem_fun (set<string> &, {unknown type})'
となってしまいました…
0925915NGNG
しかし、テンプレート引数を明示的に指定して
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   obj_mem_fun<
     pair<set<string>::const_iterator, bool>,
     set<string>,
     const set<string>::value_type &
   >(coll, &set<string>::insert));
とすればコンパイルもでき、動作しました。
これで、915-916で思ってたことは、ほぼ満足です。
(テンプレート引数を明示しなければいけないのが
ちょっと残念だけど。)
0926915NGNG
で、またまた疑問なんですが、のコンパイルエラーは
仕様なんでしょうか、バグなんでしょうか、それとも
未定義な部分(実装上の制限)なんでしょうか?

それから、こういう、オブジェクトに対する呼びだし
obj.message(arg1) を普通の関数呼びだし func(arg1)
の形式に変換する関数アダプタって、標準的にあって
も良さそうな気がするんですが、boost とか、そういう
準標準ライブラリとして、こういうものってないんで
しょうか?
0927915NGNG
< で、またまた疑問なんですが、のコンパイルエラーは

う、書き間違えました。これは

> で、またまた疑問なんですが、924のコンパイルエラーは

でした。
0928デフォルトの名無しさんNGNG
boostのbindを調べてください
0929デフォルトの名無しさんNGNG
template <typename ReturnType, typename Class, typename Arg1Type,typename Class2>
inline obj_mem_fun1_t<ReturnType, Class, Arg1Type>
obj_mem_fun(Class2 &object, ReturnType (Class::*mf)(Arg1Type))
{
return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf);
}

こうしたらVC7でとおった
0930デフォルトの名無しさんNGNG
>>926
何がやりたいのかよくわからん
0931915NGNG
>>928

ドキュメントを読んで下記を試してみたところ、期待通りに
動作しました。
 for_each(
  istream_iterator<string>(cin),
  istream_iterator<string>(),
  boost::bind< pair<set<string>::const_iterator, bool> >(
   boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
素晴らしいです。どうもありがとうございました。

最初は下記のやり方を試したんですが、こちらの書き方だと、
自作のもっと単純な型に対しては動くんですが、set<string>
に対しては、924 と同様の症状でコンパイルに失敗してしまいました。
 for_each(
  istream_iterator<string>(cin),
  istream_iterator<string>(),
  boost::bind(&set<string>::insert, boost::ref(coll), _1));
0932デフォルトの名無しさんNGNG
>>931
> boost::bind< pair<set<string>::const_iterator, bool> >(
>   boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
その使い方だったらboost持ち出すまでもなく
bind1st<...>( mem_fun(&set<string>::insert), &coll )
でよくない?
0933915NGNG
>>932
なるほど。言われてみれば確かにその通りです。
mem_funを使って
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   bind1st(
 mem_fun<
   pair<set<string>::const_iterator, bool>,
   set<string>,
   const set<string>::value_type &
 >(&set<string>::insert),
 &coll));
とするか、あるいはmem_fun_refを使って
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   bind1st(
 mem_fun_ref<上に同じ>(&set<string>::insert),
 coll));
とすれば、うまく行く筈ですね… と思ってやってみたら、
例の「参照への参照」問題が発生して、どちらもコンパイル
エラーになってしまいました…

bind1stが定義する関数オブジェクトの呼びだし時に、
set<string>::insert() の引数型(const string への参照です)
への参照型を使って渡そうとするのが、原因のようです…
0934デフォルトの名無しさんNGNG
うーんgcc3.2.2(MinGW)ではコンパイルに失敗するね。
移し間違えているのかな?

std::set<std::string> coll;
std::for_each(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
boost::bind<std::pair<std::set<std::string>::const_iterator, bool> >(
boost::mem_fn(&std::set<std::string>::insert), boost::ref(coll), boost::lambda::_1));

C:/MinGW/boost/set_insert.cpp: In function `int main()':

C:/MinGW/boost/set_insert.cpp:19: no matching function for call to `
mem_fn(<unknown type>)'
0935915NGNG
あれれ、unknown typeになりますか。mem_fn()のテンプレート引数を
明示的に指定するとどうでしょう?
set<string> coll;
for_each(istream_iterator<string>(cin), istream_iterator<string>(),
  boost::bind< pair<set<string>::const_iterator, bool> >(
    boost::mem_fn<
      pair<set<string>::const_iterator, bool>,
      set<string>,
      const set<string>::value_type &
    >(&set<string>::insert), boost::ref(coll), _1));
手元の環境だと、この場合、bind()の方のテンプレート引数は
省略可能になります。
0936デフォルトの名無しさんNGNG
>>935
さらに強烈なエラーが出てきました。

C:/mingw/include/boost/bind.hpp: In member function `R boost::_bi::list2<A1,
A2>::operator()(boost::_bi::type<R>, F, A&) const [with R =

std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, F =
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const
std::string&, const std::string*>, bool>, std::set<std::string,
std::less<std::string>, std::allocator<std::string> >, const std::string&>,
A = boost::_bi::list1<const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&>, A1 =
boost::reference_wrapper<std::set<std::string, std::less<std::string>,
std::allocator<std::string> > >, A2 =
boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
> >]':
0937デフォルトの名無しさんNGNG
C:/mingw/include/boost/bind/bind_template.hpp:33:
instantiated from `boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&)
[with A1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
F = boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>,
L = boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>, std::allocator<std::string> > >,
boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > >]'
C:/mingw/include/c++/3.2.2/bits/stl_algo.h:157:
instantiated from `_Function std::for_each(_InputIter, _InputIter, _Function)
[with _InputIter = std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>,
_Function = boost::_bi::bind_t<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>,
boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>,
std::allocator<std::string> > >, boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > > >]'
0938デフォルトの名無しさんNGNG
C:/MinGW/boost/set_insert.cpp:23: instantiated from here
C:/mingw/include/boost/bind.hpp:233: no match for call to `(
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const
std::string&, const std::string*>, bool>, std::set<std::string,
std::less<std::string>, std::allocator<std::string> >, const std::string&>)
(std::set<std::string, std::less<std::string>, std::allocator<std::string>
>&, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)'
C:/mingw/include/boost/bind/mem_fn_template.hpp:129: candidates are: R
boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R =
std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]
C:/mingw/include/boost/bind/mem_fn_template.hpp:134: R

boost::_mfi::mf1<R, T, A1>::operator()(U&, A1) const [with U =
std::set<std::string, std::less<std::string>, std::allocator<std::string> >,
R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]

C:/mingw/include/boost/bind/mem_fn_template.hpp:139: R
boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R =
std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]

Execution terminated
0939デフォルトの名無しさんNGNG
string文字列中の特定の文字Aを検索し、
その文字以降Bが出現するまでの文字列を抜き出したい場合
どうすればよいですか。

string str(`hoge...`);
string::iterator sp;
string::iterator ep;

sp = find(str.begin(), str.end(), 'A');
ep = find(sp, str.end(), 'B');

で要素位置はわかりますが、これをどう使えば
要素を抜き出せるのか。。。
0940デフォルトの名無しさんNGNG
string str("fawAejkreBf");
string::size_type pos=str.find_first_of('A');
if(pos!=string::npos)
{
pos++;
str=str.substr(pos,str.find_first_of('B',pos)-pos);
}
0941デフォルトの名無しさんNGNG
>>939
string AtoB(sp, ep);
0942デフォルトの名無しさんNGNG
>>936
エラーは no match for call to ですか…
なんかメソッドの signature が違っているくさいですね。
コンパイラというよりは、STL の実装の違いのような気が
するんですが、UNIX系OS上の gcc-3.2.1 では 935で問題
なく通りました。gcc-3.2.1と3.2.2で、STL回りって、
そんなに変わっているんでしょうか。
0943デフォルトの名無しさんNGNG
>>942
原因がわかりました。_1 はてっきり boost::lambda::_1 かと思ってたの
ですが、boost::bind の _1 だったのですね。
無事通りました。ありがとうございます。
gcc3.2.2でも通りました(当たり前ですよね)。

ただ、やはり boost:mem_fn のテンプレート引数を明示的に指定しないと
コンパイル通りません。
0944デフォルトの名無しさんNGNG
>>940
>>941
さま。
ありがとうございます。
0945デフォルトの名無しさんNGNG
std::ofstream ofs("test.bin",std::ios::binary);
int tmp = 12;
ofs << tmp;

こうしても、バイナリ出力にはなりませんよね。
fstream系でバイナリ入出力って無理なんですか?



もひとつ。

template<typename T>
void Hoge(const T& t){ /* 省略 */}

に対して、Tが vector<T> みたいなものだった場合は
別なことをさせたいんですが、特殊化でしょうか。
あくまでvector<T>です。まだ型は完全に
決まってないので、部分特殊化なんでしょうか?
VC6で、どうやればいいんでしょうか……?
0946デフォルトの名無しさんNGNG
>>945
バイナリイメージの出入力なら、std::ios::binary付けたうえで、
reinterpret_cast&read/writeかな。

VC6でふつうに部分特殊化したらエラーになった。
サポートできてないんだっけ?
0947デフォルトの名無しさんNGNG
>>945
部分特殊化というよりは、template関数のpartial ordering。
確かVC6では使えないので、何かトリックを使って頑張るしか無いのでは。
0948デフォルトの名無しさんNGNG
微妙にスレ違いですが、質問お願いします。

stringから、整数や実数に直接入力する方法ってありますでしょうか。
今は下記のようにやっています。
string str = "777";
int c = atoi(str.c_str());

なんていうかstdlib.hをインクルードするのが悔しいというか・・・アホですいません。
ストリームみたいに、stream >> intみたいな感じで可能ならなぁ、と。

0949ヽ(´ー`)ノNGNG
>>948
boost::lexical_cast 使え…とかそういう話?
0950ヽ(´ー`)ノNGNG
ミスって投稿しちゃった。こんな感じ。

#include <string>
#include <boost/lexical_cast.hpp>

int main(int argc, char **argv) {
string str = "777";
int c = boost::lexical_cast<int>(str);

return 0;
}
0951948NGNG
>>950
すごい!

            ・・・・boostってすごい_| ̄|○


λ...........オトシテコヨウ…


と、レスありがとうございました。すいません、環境書かなくて…。
今は腐ったVC++6付属の使ってますが、これを機に移行してみようと思います。
0952デフォルトの名無しさんNGNG
>>951
boost::lexical_castは内部的にstd::stringstreamを使っている。
バラして書けばこんな感じ。簡単だろ。

int main()
{
std::string str("123");
std::stringstream sstr(str);
int i;

sstr >> i;

std::cout << i << std::endl;
}
0953948NGNG
>>952
す、素敵すぎです!ありがとうございました。
移行はするとしても、当座はこれでしのいでみます。
0954デフォルトの名無しさんNGNG
>>953
ちなみにstd::stringstreamのコンストラクタを起動した直後は書き込み位置
も読み込み位置もゼロになっているようだから、適当にシークして追加する
と良い。本当はstd::ios::pos_typeをstd::coutに出力できない場合もあるんだ
けどね。あくまでも例って事で。

int main()
{
std::string str("123");
std::stringstream sstr(str);
int i, j;
std::ios::pos_type p;

p = sstr.tellg();
std::cout << "read pos = " << p << std::endl;
p = sstr.tellp();
std::cout << "write pos = " << p << std::endl;

sstr.seekp(0, std::ios::end);

sstr << " 456";
sstr.seekg(0, std::ios::beg);
sstr >> i >> j;

std::cout << i << ' ' << j << std::endl;
}
0955デフォルトの名無しさんNGNG
sstr.seekg(0, std::ios::beg);
はいらなかったかな。
C++のストリームはCとは違って読み込みと書き込みのポインタは
別々だからね。
0956948NGNG
>>954-955
いやはや、コードは言葉より雄弁と言いますか・・・。
分かりやすくて本当にためになりました。ありがとうございました。

読んで置いて良かった・・・正直いうと、こんな使いかたしてましたよ(笑

int main()
{
int i;
std::string str("123");
std::stringstream( str ) >> i;

std::cout << i << std::endl;
}
0957デフォルトの名無しさんNGNG
>>945

#include <vector>

template<typename T>
struct foo {
static void Hoge(const T& t)
{
*****
}
static void Hoge(const std::vector<T>& t)
{
****
}
};

foo<int>::Hoge(0);
foo<int>::Hoge(std::vector<int>());

とかじゃダメなの?
0958957NGNG
>>945

やっぱ上のじゃ不便だな、ってことで以下...

template <int N> struct foo {
template <class T> static void baka(const T& t) { //hogehoge }
};

template <> struct foo<1> {
template <class T> static void baka(const std::vector<T>& t) { //hogehoge }
};

template <class T> char hage(const std::vector<T>& t);
double hage(...);

template<typename T>
static void Hoge(const T& t) { foo<sizeof(hage(t))>::baka(t); }

void test() {
int a = 3;
std::vector<int> v(8);
Hoge(a);
Hoge(v);
}

ちゃんとディスパッチできたよ。
sizeof(char) < sizeof(double) だと規格のどこに書いてあるのか小一時間(略
0959デフォルトの名無しさんNGNG
>>956
うぉ、こんなやり方でもできるんだな
やっぱ使うのまずいっぽ?

コンストラクタで作ってから、どうなってるんだろ
デバッガで追ってみたけどテンプレートが複雑でいまいちわからん
0960デフォルトの名無しさんNGNG
>>945
ふつうにオーバーロードで
template<typename T>
void Fn(const T&){}

template<typename T>
void Fn(const std::vector<T>&){}

int main(){
Fn(int() );
Fn<int>(std::vector<int>() );//Fn<int> 明示的に型指定
return 0;
}

0961デフォルトの名無しさんNGNG
>>956
の示したコードの使い方、あれでいいんじゃないですか?
あってるよね?
0962958NGNG
>>960

なるほど<int>と限定した上ではただのオーバーロードに
なるんだね。
複雑にして損したよ
0963956NGNG
>>959 >>961
自分で書いて置いてなんですが、あってるんですか?
さすがに無理な気がしないでもないです…要するにこういう事ですよね?

#include <iostream>

class B{
public:
void hage(){
std::cout << "Hoge" << std::endl;
}
};

int main(){
B().hage();

return 0;
}

実体はどこに・・・というかうちのコンパイラ(VC++6.0)以外でも通るのだろうか。
詳しい方のご意見をお尋ねしたいところです。ってC++スレの方がいいのかな。
0964デフォルトの名無しさんNGNG
>>963

ん?一時オブジェクトの寿命の問題でしょ
全然問題ないよ
0965956NGNG
>>964
いやぁ、そうなんですか・・・また一つ勉強になりました。

てっきり、Bコンストラクタのスコープから出た瞬間、
デストラクタが呼ばれるのかと思ってました。
Bコンストラクタ>hage>Bデストラクタは保証されているんですねぇ。

うーん、ダメだ。自分この辺ぐだぐだで・・・再勉強してきます。
レスありがとうございました。
0966デフォルトの名無しさんNGNG
一時オブジェクトってのは非constな参照では受けられないけど
非constなメソッドを呼べるという特殊な存在。
この性質を利用したテクニックもある。
でもこれを多用すると一部の論者に睨まれるという諸刃の剣。
0967デフォルトの名無しさんNGNG
一時オブジェクトって、非constな参照で受けられなかったんだ……。
言われてみると、敢えて受けてみたことはないな。
thx.

0968デフォルトの名無しさんNGNG
>>966
おまけに自分自身を返すメソッドを呼ぶと
非constな参照で受けることが可能になるだけでなく
当然左辺値として扱うことも可能になる。

一時オブジェクトは非constな参照で受けることが
できない/右辺値として扱われるって
仕様はホントにあほらしいんだよなぁ。
そんなんだったら始めからエラーじゃなくて、
ワーニング程度に留めとけっての。
0969デフォルトの名無しさんNGNG
>>960

intと明示的に型指定できるくらいだったらvectorなのか
そうでないのかもわかるだろうから、オーバーロードすら
必要ないんじゃない?
0970デフォルトの名無しさんNGNG
>>969

>>945
を、よめ!!!!!!!!!

ちなみにほかのコンパイラーなら
明示的の指定はいらん
0971デフォルトの名無しさんNGNG
>>963
そういう使い方ならstatic関数にすればいいやん
B::hage(); みたいに
0972デフォルトの名無しさんNGNG
>>970

945の意味するところが『いずれテンパラはある一つの型に決めます』ってなら
<T>の部分を明示するのは抵抗ないだろうけどね。
テンパラになる型が最終的に複数出てくる場合はどうだろう。
と思って957→958という流れになったわけだが
0973デフォルトの名無しさんNGNG
staticにしたらこんなのが通らん

#include<cstdio>

//#define STATIC__
struct FuncOperator
{
#ifdef STATIC__
static void operator () (){ puts("static operator"); }
#else
void operator () (){ puts("Non static operator"); }
#endif
};

int main(){

#ifdef STATIC__

FuncOperator::operator ()();
#else
FuncOperator()();

#endif

return 0;
}
0974デフォルトの名無しさんNGNG
staticなオペレータって蟻なのか?
0975デフォルトの名無しさんNGNG
>>974

為し
0976945NGNG
>>958さん、ありがとうございます。たしかにうまくいきますね。
で、えぇと……実はHoge()はあるクラスのメンバ関数なんですが、
この場合はどうしたらいいんでしょう?^^;

条件が後出しになって申し訳ありません。詳しく状況を言いますね。
まず、バイナリの入出力を簡便にしてくれるクラスが欲しいのです。
標準だと、こうなりますよね。

ifstream ifs("piyo.dat",ios::binary);
int n;
ifs.read(reinterpret_cast<char*>(&n),sizeof(int));
vector<int> v(n);
ifs.read(reinterpret_cast<char*>(&v[0]),sizeof(int)*n);

これだとあまりにも面倒なのです。不要な指定が多すぎて。

CReadFile rf("piyo.dat");
int n;
rf >> n;
vector<int> v(n);
rf >> v

こういう感じですっきり指定できるラッパークラスを作りたいのです。
出力の方も、同じ要領でやりたいと思ってます。
これで、intだけを入出力したいわけじゃないから、templateで、
ということなんです。
で、VC6固有の(ですよね?)templateヘタレ解析に悩まされてるわけです。
そういうわけですので、>>960さんみたいなやり方は、クラス使用者の
負担になりますので、あんまり意味がないわけです。
>>958さんのやり方みたく、多少機種依存の部分があっても、なんとか
隠蔽できればいいんですけど……。
0977デフォルトの名無しさんNGNG
して、次スレの方は?
0978デフォルトの名無しさんNGNG
>>976
template <class T> void hoge(const T &);
を用意しなければいいのでは

つまり
void hoge(int);//unsigned int,float,なども用意する
template <class T> void hoge(const vector<T> &);

でどうでしょう? あんまり無条件でバイナリ保存できる型なんてそうそうないでしょ?
逆に安全性の面から用意されていないと入出力できないようにしたほうが良いとおもわれ
0979デフォルトの名無しさんNGNG
reinterpret_cast<?>(?)のなにがいやぁーなの
もしながくていやとかぬかしてんのそれなら(char*)キャスト使えば
もし、それでもかっこ悪いとか言うんなら自分でvector<T>専用をつくれば

template<typename T>char* Cast(std::vector<T>& tt)
{return reinterpret_cast<char*>(&tt[0]); }

こんな感じに。
さらにintとunsigned charを使い分けたいなんて我侭もあるんなら

union bit{
int i;
unsigned char bitn[4];
};
std::vector<bit>これで読み込ませればint、
unsigned charの使い分けが一回の作業で実現できよう。
とにかくreinterpret_castぐらいでクラスなんて作ってられない


0980デフォルトの名無しさんNGNG
#define scast static_cast
#define rcast reinterpret_cast
#define ccast const_cast
#define dcast dynamic_cast
0981デフォルトの名無しさんNGNG
template <class T,class U> T scast(const U &u)
{ return static_cast<T>(u); }
0982デフォルトの名無しさんNGNG
>>980
それをやるならここでは、こうでしょ。。
#define Cast(M) reinterpret_cast<char*>(M)
0983デフォルトの名無しさんNGNG
>>981
いみない。結局明示的に指定しなくちゃならんでしょ
0984デフォルトの名無しさんNGNG
http://www.tietew.jp/cppll/archive/1071
キャスト
0985デフォルトの名無しさんNGNG
>>982
char * 型以外に使えないじゃん。
0986デフォルトの名無しさんNGNG
ねえ、早く!
0987スレタイはこれでNGNG
template<typename STL,Boost,Loki,etc>class part2
0988デフォルトの名無しさんNGNG
>>987
<> は化けるのでは?
0989デフォルトの名無しさんNGNG
一応新スレ立てときました。

【C++】template 統合スレ -- Part2
http://pc2.2ch.net/test/read.cgi/tech/1047978546/
0990 NGNG
〈〉←これで代用という手がある。
0991デフォルトの名無しさんNGNG
777?
0992デフォルトの名無しさんNGNG
この板では1000ゲットは興味なしですか?
0993デフォルトの名無しさんNGNG
ぬるぽがこのスレに興味を持ったようです。

  ∧_∧
 ( ´∀`)< ぬるぽ
レス数が950を超えています。1000を超えると書き込みができなくなります。