トップページ⇒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 あたりに。
0609デフォルトの名無しさんNGNG
>>607
イテレータ同士の比較とか、C 関数に渡す場合には使えるよね。

/* 要素数 num の int 配列を処理する */
extern "C" void foo(int *data, size_t num);

vector<int> v;
..
foo(&vec[0], vec.size());
0610デフォルトの名無しさんNGNG
596です
解決しました。
思いっきり勘違いしてました。最終的に以下のようになりました。
ありがとうございました。
//.h
struct mySet {
virtual void insert(AnsiString&) = 0;
virtual unsigned int getSize(void) = 0;
typedef std::set<AnsiString>::iterator iterator;
virtual iterator begin(void) = 0;
virtual iterator end(void) = 0;
};
//.cpp
auto_ptr<mySet> pSet;
if(RepeatDataCheckBox->Checked)//重複なし
{
auto_ptr<UniqueSet> instance (new UniqueSet());
pSet = instance;
}
else //重複あり
{
auto_ptr<MultiSet> instance (new MultiSet());
pSet = instance;
}
pSet->insert(tmp);
typedef std::set<AnsiString>::iterator iterator;
for(iterator it = pSet->begin();it!=pSet->end();++it)
{
ed->Lines->Add(*it);
}
0611デフォルトの名無しさんNGNG
v[n]は*(v.begin()+n)と定義されていて(23.1.1 -12-)、
v.empty()のとき、v.begin()は"past-the-end"っていう値を返すことになってる(23.1 -7-)。
イテレーターiについて、*iが定義されるようなiの値を、"dereferencable"っていう
けど、"past-the-end"は"dereferencable"じゃぁない(24.1 -5-)。

ってことで、v.empty()のとき、v[0]は
"dereferencable"ではないイテレーターに operator * を適用することになるので、
未定義である。

あとから & つけたところで手遅れだと思われ。
0612605NGNG
仕様書調べてみたよ。

コンテナ a の operator[](int n) は *(a.begin() + n) と定義されているから、n = 0 のときに
*a.begin() (== *a.end()) が許されるか否かが問題。

a.end() は常に past-the-end-value (有効な要素の『次』を指す) イテレータを返し、これ
は

> 24.1 Iterator requirements
> 6. (前略) Values of an iterator i for which the expression *i is defined are called
> dereferenceable. The library never assumes that past-the-end values are
> dereferenceable

ということでデリファレンスしてはいけない。つまり *a.begin() という表記は NG で、
従って &a[0] も NG ってことになる。

ただし、現実には参照はコンパイラ内部ではポインタとして実装されてるから

vector<int> v;
int& n = &v[0];
int* p = &n;

とした場合でも p (n のアドレス) だけ見てる分には問題ない。ただし *p = 1 とか
int x = *p といったように、n の値を読み書きすると、一般保護違反で落ちたりメモリ
壊したりする。

……ってことかね。
0613605NGNG
一足遅かったか…
0614デフォルトの名無しさんNGNG
>>610
その場合、mySetのデストラクタにvirtualが要る。

MultiSetの実装が謎だ。なんでコンパイルとおるんだ?
絶対解決してないと思うんだが?
0615デフォルトの名無しさんNGNG
>>611
vector<T>::iterator が T* という良くある環境だと問題ないけど、STLport の
デバッグモードみたいに別の型が返ってくる(それをデリファレンスすると T
になる)だと、怒られそうな気がする。

とはいえ微妙に使いにくい仕様だな、これ。>>609 にあるような C 言語の関
数を呼ぶ場合、どうせ C 関数の方で要素数チェックして 0 なら何もしない、
ってのが普通だし、そっちにチェックを任せたいよな。
0616611NGNG
ニヤリ
0617デフォルトの名無しさんNGNG
610です
このようにしましたけど、問題ないようです。
環境はBCB5でWindowsXPです。

//重複なしのコンテナ
class UniqueSet : public mySet {
std::set<AnsiString> container_;
std::set<AnsiString>::iterator itrator_;
public:
void insert(AnsiString& s) { container_.insert(s); }
unsigned int getSize(void){ return container_.size(); }
iterator begin(void){ return container_.begin(); }
iterator end(void){ return container_.end(); }
};
//重複ありのコンテナ
class MultiSet : public mySet {
std::multiset<AnsiString> container_;
std::multiset<AnsiString>::iterator itrator_;
public:
void insert(AnsiString& s) { container_.insert(s); }
unsigned int getSize(void){ return container_.size(); }
iterator begin(void){ return container_.begin(); }
iterator end(void){ return container_.end(); }
};
0618デフォルトの名無しさんNGNG
std::set<int>::iterator f() { return std::multiset<int>::iterator(); }

gccでも↑のコードがエラーにならん。
仕様じゃ、ないよな?
0619デフォルトの名無しさんNGNG
>>615
size()==0よりもempty()を使えって話になるんじゃないか?
0620デフォルトの名無しさんNGNG
>>619
それでも

extern "C" void foo(int *data, size_t num);

に対して、これを利用する C++ 側関数は

vector<int> v;
if (!v.empty())
  foo(&v[0], v.size());

と場合分けが必要になるよね。
0621デフォルトの名無しさんNGNG
>>620
↓で問題ないと思う。

inline
void foo( vector<int>& v )
{
  if(!v.empty())
    foo(&v[0],v.size());
}
0622デフォルトの名無しさんNGNG
>>621
俺だったらこんな関数作って使うかな。

templat<class T>
inline T* GetFirstPointer( vector<T>& v )
{
 if(v.empty())
  return NULL;
 else
  return &v[0];
}

で、vectorが空でも&v[0]が許される実装で、
かつ効率が気になる場合は
単純に&v[0]を返すように書き換えると。
0623622NGNG
↑
誤:templat<class T>
正:template<class T>
0624デフォルトの名無しさんNGNG
>>622
>621のコードを見てなお、>622のコードを使いたくなるのって、どんなとき?
0625デフォルトの名無しさんNGNG
悲しいときー
0626デフォルトの名無しさんNGNG
>>624
ラッパ関数を沢山書くのが面倒な場合だろう。
0627622NGNG
>>624
fooに相当する関数が沢山あるとき。
0628622NGNG
カブった....。

あとfooが関数オブジェクトだった時や、
fooがvectorのサイズを変更しないことを示したい時にも
>622の方を使いたくなるな。
0629デフォルトの名無しさんNGNG
>>627
ということは、末端のコードにGetFirstPointerがばら撒かれるわけか。
  foo(GetFirstPointer(v),v.size());
・・・うーん、あんまり賛成できないなぁ。
0630629NGNG
>>628
> fooがvectorのサイズを変更しないことを示したい時にも

あー、それあるなぁ。
やっぱりしょうがないかぁ。
0631デフォルトの名無しさんNGNG
>>629
いっそ vector 継承して operator[] だけ再定義したオブジェクトを作るのも
手かもしれんな。

メンバ変数は一切増えないから、デストラクタが virtual でなくとも支障ない
しさ。
0632629NGNG
>>631
そりゃあんまりだ。
0633デフォルトの名無しさんNGNG
>>611-612
でもさ、vector::operator[] って reference を返すじゃん。
てことは、&v[0] は dereference を実行してないと思うんだけど。

まあでも、v.size() == 0 の場合、要素配列を格納するための
有効なバッファがが確保されているかどうかは不明だしねぇ。
やっぱり v.empty() で切り分けるしかないかなぁ。
0634デフォルトの名無しさんNGNG
>>633
> でもさ、vector::operator[] って reference を返すじゃん。
で、規格書読むと reference は「有効なオブジェクトを指さねばならない」と書いてあったり
するわけだ。

> てことは、&v[0] は dereference を実行してないと思うんだけど。
これは &(*v.begin()) と同じ意味なんだが、v.begin() が返すのが単なるポインタではない
場合には、実際に dereference が行われた上で、そのアドレスが計算されることになる。
たいていの処理系だと vector<T>::iterator は T* だから問題ないけど。
0635601NGNG
>>592
やはり別の理由でした。自作スマートポインタが、変な形式の operator new を持っていたのがいけなかったようです。
(g++ に切り替えてわかったのですが、boost::mem_fn ではなくて、その前のコンテナに突っ込むところでのエラーだったようです。)
それを取り除いて、自作ポインタ用の get_pointer を追加した所、うまくいきました。

ありがとうございました。
0636635NGNG
それと気がついた事を一つ。

get_pointer は koenig look-up があるので 名前空間 boost に入れなくても
よさそうです。
0637592NGNG
>>636
VC6って演算子じゃない関数は Koenig Lookup 出来ないんじゃなかったっけ。
最近使ってないからはっきり覚えてはいないけど…。
0638デフォルトの名無しさんNGNG
昔、数値計算用に3次元や2次元ベクトルクラス(double型のみ)を自作したりしたんだけど、
最近になってテンプレート化してみたら、同じ型同士は問題なく動くけど
違う型を混ぜると下のように怒られちゃいました。
型をあわせなきゃいけないみたいだけどどうすればいいのでしょう……


borland c++ 5.5でつ

vec3<double> a
vec3< complex<double> > b,c

c=a*b;

『エラー E2094 : * 演算子が使われたがクラス Vec3<complex<double >> では Vec3<double> 型のための定義が存在しない』
0639デフォルトの名無しさんNGNG
vec3<double> + vec3< complex<double> > で、あなたの書いたどのコードが
実行されると期待しているんだ?
0640デフォルトの名無しさんNGNG
>>638
本質的には T から U への型変換が存在する時に、vec<T> から vec<U> への
型変換を認めたい、って話だよね。

それなら、テンプレート化したコピーコンストラクタを作る。vec3 の実装がどうなっ
てるか知らんけど、かりに vec3<T> が private 変数として T 型の配列 v_[3] を
持つと仮定すると、

template <typename T>
class vec3
{
public:
  template <typeename U>
  vec3(const vec3<U>& other)
    : v_(other.v_)
  {}
};

ってな感じ。other.v_ (U[3]型) から v_ (T[3] 型) への暗黙の型変換がある場合、
これでよろしく変換できる。
0641デフォルトの名無しさんNGNG
ありがとう。何を調べればよいのかが解らないと自分一人ではどうにもならんので。

配列だと余分なアクセス入るかなと思って、ベクトルの各成分はT v[3]じゃなくてT x,y,zで実装してます。
もっと次数が高ければ当然配列にするだろうけど……あ、配列だったらSTLのvector使えばいいのか。

明日試してみます
0642デフォルトの名無しさんNGNG
テンプレートクラスをstd::ostreamに出力するにはどのように定義すれば
いいのでしょうか?
コンパイルできるのですがワーニングが出ます。gcc3.2.1(MinGW)です。

template <typename T>
class A {
T value;
public:
A(double d = 0) {
value = d;
}
friend std::ostream& operator<<(std::ostream& os, const A<T>& a);
};

std::ostream& operator<<(std::ostream& os, const A<double>& a)
{
os << a.value;
return os;
}

int main()
{
A<double> a(1.23);
std::cout << a << std::endl;
}
0643デフォルトの名無しさんNGNG
>>642
なんでそのコンパイラの出力をはぶきやがるんだ?
0644デフォルトの名無しさんNGNG
>>643
すみません、ワーニングをコピペします。

g++.exe "C:\MinGW\Learn\Learn2\template_ostream.cpp" -o "C:\MinGW\Learn\Learn2\template_ostream.exe" -Wall -s -O3 -I"C:\mingw\include" -I"C:\mingw\include\c++" -I"C:\mingw\include" -L"C:\mingw\lib"
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: friend declaration `
std::ostream& operator<<(std::ostream&, const A<T>&)' declares a
non-template function
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: (if this is not what
you intended, make sure the function template has already been declared and
add <> after the function name here) -Wno-non-template-friend disables this
warning

Execution terminated
Compilation successful
0645デフォルトの名無しさんNGNG
>>644
Friend declaration `std::ostream& operator<<(std::ostream&, const A<T>&)'
declares a non-template function.
If this is not what you intended, make sure the function template has
already been declared and add <> after the function name here.
-Wno-non-template-friend disables this warning.

・・・ってなワケだ。あとは好きなように対処しな。
0646デフォルトの名無しさんNGNG
>>645
次のようにしたらコンパイル通りました。ありがとうございました。
ちなみにBCC5.6では通りませんね。

template <typename T>
class A {
T value;
public:
A(double d = 0) {
value = d;
}
friend std::ostream& operator<< <>(std::ostream& os, const A<T>& a);
};

template <typename T>
std::ostream& operator<<(std::ostream& os, const A<T>& a)
{
os << a.value;
return os;
}

int main()
{
A<double> a(1.23);
std::cout << a << std::endl;
}
0647636NGNG
>>637
なはは…うっかり忘れてました。
その間についに VC++ に別れを告げる決意を固めて、試したのは g++ 上でした。

VC++ では通らないかもしれないです。
0648638NGNG
>640
無事complex<double> とdouble間の計算が出来ますた。有難う
0649デフォルトの名無しさんNGNG
テンプレート引数の型を文字列リテラルとして取り出したいんですが
どうすればいいでしょう。つまりログとりたいんです

template<typename T>
class Hoge {
public:
 Hoge() {
  Log::debug("Hoge<T>::Hoge()");
 }
};

Hoge<int> hoge;

で Hoge<int>::Hoge() と表示してほしいんですが・・・
0650デフォルトの名無しさんNGNG
>>649
typeid(T).name()
0651デフォルトの名無しさんNGNG
>>649
typeid(T).name()
0652651NGNG
>>650
ケコーン
0653デフォルトの名無しさんNGNG
それはconst char*でして、文字列リテラルではないかと・・・
コンパイル時に Hoge<int>::Hoge になって欲しいんです・・・
0654デフォルトの名無しさんNGNG
>>653
無理。
std::string でも使え。
0655デフォルトの名無しさんNGNG
ガビーン
あきらめます・・・
0656 NGNG

"<" と ">" に挟まれた文字列を検索して格納したいのですが。
これで良いでしょうか?

{
    std::string text;
    std::string __text;
    std::string::iterator i_first;
    std::string::iterator i_last;

    i_first = __text.begin() + __text.find( "<", 0 ) + 1;
    i_last = __text.begin() + __text.find( ">", 0 );

    text.assign( i_first, i_last );
}
0657デフォルトの名無しさんNGNG
>>656
例えばこんなのはどうか。

std::string text;
std::string __text;
std::string::iterator i_first;
std::string::size_type st;

i_first = __text.begin() + __text.find("<") + 1;
st = __text.find(">") - __text.find("<") - 1;

text.assign(i_first, st);
0658デフォルトの名無しさんNGNG
これでもいい。
std::stringはイテレータよりもインデックスで扱った方が
扱いやすいようだ。

std::string text;
std::string __text("aaa<abc>def");
std::string::size_type st, st2;

st = __text.find("<") + 1;
st2 = __text.find(">") - __text.find("<") - 1;

text = __text.substr(st, st2);
0659デフォルトの名無しさんNGNG
文字列が"abd>efg<hijklmn"とかだと破綻しねぇか? 全部。
0660デフォルトの名無しさんNGNG
>>659
エラーチェックしてないから。したらしたなりになる。
0661デフォルトの名無しさんNGNG
>>656
boost::regex使えばいいのに。
0662656NGNG
正規表現で探すのは後に実装する予定でした。
とりあえず抽出だけを考えてます
それで、関数を作ってみました。

const std::string Extraction
(
const std::string text,
const std::string text_open,
const std::string text_close
)
{
std::string output = "";
std::string::size_type position_open = 0;
std::string::size_type position_close = 0;
std::string::size_type position_target = 0;

position_open = text.find( text_open, 0 );
if( position_open == std::string::npos ) return ( const std::string )"";

position_close = text.find( text_close, position_open );
if( position_close == std::string::npos ) return ( const std::string )"";

position_target = position_open + text_open.length();

output.assign( text, position_target, position_close - position_target );

return ( const std::string )output;
}
0663656NGNG
使用してみました

std::string t;
t = Extraction( "a<b<c<d", "<", ">" ); // 無
t = Extraction( "a<b<c>d", "<", ">" ); // b<c
t = Extraction( "a<b>c<d", "<", ">" ); // b
t = Extraction( "a<b>c>d", "<", ">" ); // b
t = Extraction( "a>b<c<d", "<", ">" ); // 無
t = Extraction( "a>b<c>d", "<", ">" ); // c
t = Extraction( "a>b>c<d", "<", ">" ); // 無
t = Extraction( "a>b>c>d", "<", ">" ); // 無

STL 初心者なもので、色々と不具合があるかもしれません。
みなさんどうもありがとうございました
0664デフォルトの名無しさんNGNG
>>662

これではいかぬか

const std::string Extraction
(const std::string& text, const std::string& text_open, const std::string& text_close)
{
std::string::size_type position_open = text.find(text_open), position_close, position_target;

if (
position_open == std::string::npos
|| (position_close = text.find(text_close, position_open)) == std::string::npos
|| (position_target = position_open + text_open.length()) > position_close
)
return std::string();
else
return std::string(text, position_target, position_close - position_target);
}
0665デフォルトの名無しさんNGNG
boost::shared_ptrのような非進入型参照カウンタを使ったスマートポインタって
スマートポインタ同士の直接代入はできるけど、
スマートポインタから生ポインタを取り出して、それを別のスマートポインタに入れると参照カウントの二重管理になって悲惨な結末になるんですよね。

んで、普段は可能な限りスマートポインタを使うことでどうにかなるんですけど、
一ヶ所だけ絶対にスマートポインタが使えないところがあって、
つまり this ポインタなんですけどね。

boost::shared_ptr< MyType > MyType::GetObject( std::string name )
{
 return boost::shared_ptr< MyType >( this->name==name ? this : new MyType( name ) );
}

みたいな必要があったとき、皆さんならどうしますか?
私はもうぜんぜん思いつかないんで進入型に切り替えるしかないかなぁとか思ってますが。
0666デフォルトの名無しさんNGNG
その場合MyTypeを管理している上位クラスが全部責任を持つ構造にする。
0667デフォルトの名無しさんNGNG
STLportのhashって使ってみられた方いらっしゃいます?
0668デフォルトの名無しさんNGNG
>>667
hash_map ではなくて、ハッシュ値を計算する hash の方? 使った事はあるけど。
0669デフォルトの名無しさんNGNG
>>668
hashのアルゴリズムは処理系依存なんですよね。
どういう仕組みで発生しているのか興味があります。
0670デフォルトの名無しさんNGNG
>>669
> hashのアルゴリズムは処理系依存なんですよね。
STLport の hash の話をしてるなら、処理系非依存だが。stl/_hash_fun.h に
書いてあるから読んでみ。

ちなみにテンプレートクラスとして定義されているので、ユーザ定義クラスに対する
ハッシュ値は、自分で specialization しないと計算できない。
0671デフォルトの名無しさんNGNG
>>670

inline size_t __stl_hash_string(const char* __s)
{
_STLP_FIX_LITERAL_BUG(__s)
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5*__h + *__s;

return size_t(__h);
}

これでしょうか。割と簡単な事してるんですね。ありがとうございました。
0672デフォルトの名無しさんNGNG
LokiのVC6Port(↓)にReferredTypeやPointeeTypeを実装するのは
無理かなあ?
isEnumとisMemberFuncPointerは出来たので送ったら反映されたん
だけど誰かアイデアない?

http://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport
0673デフォルトの名無しさんNGNG
ファイルの内容を表示するプログラムを作ってみたのですが、
改行を表示してくれません。どこを直せば良いでしょうか。

int main()
{
std::ifstream ifs("copy1.cpp");

std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout));
}
0674デフォルトの名無しさんNGNG
>>673
std::istream_iterator<type>(i)は、i >> t を内部で実行しているため、
ホワイトスペース文字はスキップされて読み込まれない。
0675デフォルトの名無しさんNGNG
>>674
ありがとうございます♪
意外でした。std::getlineか何かで読み込んでみることにします。
0676デフォルトの名無しさんNGNG
>>675

std::noskipwsをストリームに食わせてやれば、ホワイトスペース
文字も読み込める。

int main()
{
std::ifstream ifs("copy1.cpp");

ifs >> std::noskipws;
std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout));
}
0677デフォルトの名無しさんNGNG
> ifs >> std::noskipws;

何か、「食わせてる」 って気がしないよな。
0678デフォルトの名無しさんNGNG
ちなみにそういう場合は[io]streambuf_iteratorを使ったほうが速いぞ、と。
0679デフォルトの名無しさんNGNG
某所で見かけた静的配列の長さを調べるコード。ちょっと感動した。

template< typename T, size_t N >
inline size_t length_of( T(&)[N] ) throw(){ return N; }

それを参考にした、静的配列の最後の要素を得るコード
template< typename T, size_t N >
inline T& last_element_of( T(&array)[N] ) throw()
{
 return array[N-1];
}
0680デフォルトの名無しさんNGNG
なるほどこれなら単純で良いね。

int main()
{
std::ifstream ifs("copy1.cpp");

std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout));
}
0681デフォルトの名無しさんNGNG
STLportって何がいいの?ラインセンスもアレだし。
0682デフォルトの名無しさんNGNG
>>679
ちなみに某所ってどこよ?他にもお宝眠ってたりせんかの?
0683デフォルトの名無しさんNGNG
>>682
たぶん ttp://www.kmonos.net/wlog/23.php あたりか?
でもこれ自体は別に新しくもない話題だよ。
ttp://www.ganaware.org/D/diary/2000-07.html
0684679NGNG
>>682
tp://www.issei.org/diary/ にて。
>>683
そーだったのか…
0685682NGNG
>>684
なるほろthx!
>>683
まぁまぁそう言わんと。知らん人間にとっては新しくなくても十分面白かったんで。
0686デフォルトの名無しさんNGNG
>>684
その日記の元ネタは cuj web site の記事。URL を忘れたので元記事へのリンクを
張らなかったんだが、google に掛け合って見つけてきたよ。制限事項に関しても詳
しく書いてあるから、ざっと読んでおくと良いと思いかと。

http://www.cuj.com/articles/1999/9902/9902h/9902h.htm?topic=articles

これに関連した小ネタだと、std::for_each のような一定範囲を扱うアルゴリズムに
次のような多重定義をしておくってのもある。for_each や find_if は、コンテナ全部
に適用したいケースが多いから。

template <class T, class TFunc>
inline TFunc for_each(T& col, TFunc f)
{
  return std::for_each(col.begin(), col.end(), f);
}

template <class T, int N, class TFunc>
inline TFunc for_each(T (&ary)[N], TFunc f)
{
  return std::for_each(&ary[0], &ary[N], f);
}

template <class T, int N, class TFunc>
inline TFunc for_each(T const (&ary)[N], TFunc f)
{
  return std::for_each(&ary[0], &ary[N], f);
}
0687デフォルトの名無しさんNGNG
lokiのSmartPtrを使ってるひとはいますか?
あれがもっとも汎用的でいいと思うのですが
なんでboostには含まれないのかな?
0688デフォルトの名無しさんNGNG
>>687
つかってまつ。gcc 2,95のバグに悩まされました。
0689デフォルトの名無しさんNGNG
>>687
いま、ちょうどboostのMLでLokiの人含めて色々議論してるようだから読んでみれば?
0690デフォルトの名無しさんNGNG
>>687
boost-mlでなんか今 auto_ptr みたいな挙動をどーするか
議論してるよ。boostに取り込まれる予定なはず。いつかは知らんけど。
0691690NGNG
ぐはぁ、かぶった。逝ってきまふ・・・
0692デフォルトの名無しさんNGNG
>>691
逝かんで良いから、議論の流れをザクッと要約してくれると嬉しい。
0693690NGNG
>>692
無理でふ。サラッと見ながら
「あー、なんかモメてるっぽいなぁ」
程度にしか読んでいないので・・・
「結論出たら結論だけ見ればいいや」
と思ってるんであんま(全然)流れ追ってないんですわ。

ちなみに今は配列のサポートでまた何やら議論してるみたい。
これも別にマトモに追ってないんですけど。
0694デフォルトの名無しさんNGNG
>>680
単純がいいなら、こっちにしとけば?
main()
{
std::ifstream ifs("copy1.cpp");
std::cout << ifs.rdbuf();
}
0695デフォルトの名無しさんNGNG
>>694
何と!簡単ですね!
0696デフォルトの名無しさんNGNG
それってどれくらいメモリ食うの?
0697デフォルトの名無しさんNGNG
>>686
参考になりました。Thanks!
0698デフォルトの名無しさんNGNG
>>696
「それ」ってなに?
0699デフォルトの名無しさんNGNG
>>698
>>694
0700デフォルトの名無しさんNGNG
>>699
なんで「メモリ食う」なんて思ったんだ?
ファイルの読み取りバッファと標準出力の
書き込みバッファくらいしか思いつかないんだが。
0701デフォルトの名無しさんNGNG
>>700
いや、内部的に何が起こるのかなと思って。
0702デフォルトの名無しさんNGNG
>>701
「内部的」なことは当然わからんが、
1文字ずつ読んだ場合に比べて余分に
メモリを必要とする理由はなにもない。
0703デフォルトの名無しさんNGNG
低レベルな質問で申し訳ないですが,
binary_function<Arg1, Arg2, RetVal>にはoperator()
定義されてないんでしょうか?
cout << plus<int>()(2,3) << endl;
は上手くいくのに,
binary_function<int, int, int> fn = plus<int>();
cout << fn(2, 3) << endl;
は上手くいきません.
0704デフォルトの名無しさんNGNG
>>703
定義されてない。
operator()は仮想関数じゃないよ。
0705703NGNG
では,関数オブジェクトを引数として渡したい場合は,
引数の型は何にしたらいいんでしょうか?
0706デフォルトの名無しさんNGNG
>>705
ふつうはテンプレートの型引数だな。
template<typename BinaryFunction>
void f(BinaryFunction fn);
0707703NGNG
<algorithm>以下の関数でもそうしてましたが,
テンプレートで取り込もうとすると,
色々と面倒な事起こりませんか?
出来れば,引数として取り込みたいのです.
0708デフォルトの名無しさんNGNG
>>707
別に面倒なことなんかないが?
0709703NGNG
すいません.↑意味不明でしたね.
様はtemplateは使わずに,
void f(binary_function<int, int, int> fn);
みたいな感じで使いたいのです.
binary_functionはlessやらplusやらの基底クラスらしいですが,
共通に使われるであろうoperator()を仮想関数として定義
してないんじゃ使えないですね.
引数としてこのクラスの関数オブジェクトを読み込む場合,
この代わりに何を基底クラスとして使うべきなのでしょうか?
■ このスレッドは過去ログ倉庫に格納されています