bind1st と mem_fun_ref – プログラミング – Home

通知
すべてクリア

bind1st と mem_fun_ref


mkz
 mkz
(@mkz)
ゲスト
結合: 18年前
投稿: 2
Topic starter  

環境は eclipse, cygwin-gcc 3.4.4

#include <iostream>
#include <functional>

class Hoge
{
public:
void func(int v)
{
std::cout << v << std::endl;
}
};

int main()
{
Hoge h;

//std::bind1st(std::mem_fun(&Hoge::func),&h)(10);
std::bind1st(std::mem_fun_ref(&Hoge::func),h)(10);
//std::bind2nd(std::mem_fun_ref(&Hoge::func),10)(h);
}

std::bind1st(std::mem_fun_ref(&Hoge::func),h)(10); の行でコンパイルエラーになり
ます。
Hoge::func(int v) を constメンバ関数にすればエラーになりません。
std::mem_fun_ref(&Hoge::func)(h, 10) とすれば期待通りの結果になります。
std::bind1st を通すとエラーになってしまいます。
なぜ、const を付ければコンパイルが通るのか教えてください。

以下がエラー内容です

/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h: In member
function ~typename _Operation::result_type
std::binder1st<_Operation>::operator()(const typename
_Operation::second_argument_type&) const [with _Operation =
std::mem_fun1_ref_t<void, Hoge, int>]':
../CppTest.cpp:22: instantiated from here
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:406: error: no
match for call to ~(const std::mem_fun1_ref_t<void, Hoge, int>) (const Hoge&,
const int&)'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:826: note:
candidates are: void std::mem_fun1_ref_t<void, _Tp, _Arg>::operator()(_Tp&,
_Arg) const [with _Tp = Hoge, _Arg = int]
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:406: error:
return-statement with a value, in function returning 'void'


引用解決済
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

mem_fun(_ref) はこの際無関係であり、話は bind の特性だけに関係します。

「なぜか」の答えは「そう規格書が定めているから」でしょうね。
bind1st, bind2nd はそれぞれヘルパークラス binder1st binder2nd を使うけど
binder1st, binder2nd のコンストラクタは const な operation しか認めません。

本来 bind1st/2nd はこんなふうに使うもので
const int array[5]={1, 2, 3, 4, 5};
const int* p1=std::find_if(array+0, array+5, std::bind1st(std::greater<int>(),
3));
const int *p2=std::find_if(array+0, array+5, std::bind2nd(std::greater<int>(),
3));
# p1 p2 が何になるか、机上で検討した後に、実行してみましょう

関数オブジェクト (この場合は greater) の operator() が non-const では、
その operator() を使う側にとって限りなく使いづらい、と思いませんか?
その辺が策定理由かと。


返信引用
mkz
 mkz
(@mkz)
ゲスト
結合: 18年前
投稿: 2
Topic starter  

> binder1st, binder2nd のコンストラクタは const な operation しか認めません。

では、なぜ
std::bind2nd(std::mem_fun_ref(&Hoge::func),10)(h);
は、const をつけなくてもコンパイルエラーにならないのでしょうか?

>const int array[5]={1, 2, 3, 4, 5};
>const int* p1=std::find_if(array+0, array+5, std::bind1st(std::greater<int>(),
3));
>const int *p2=std::find_if(array+0, array+5, std::bind2nd(std::greater<int>(),
3));
># p1 p2 が何になるか、机上で検討した後に、実行してみましょう

p1 = &array[0]
*p1 = 1
p2 = &array[3]
*p2 = 4

>関数オブジェクト (この場合は greater) の operator() が non-const では、
>その operator() を使う側にとって限りなく使いづらい、と思いませんか?

あまりピンときませんが、「メンバ変数が書き換えられる可能性がある」
ので「使いづらい」のでしょうか?


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました