環境は 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'
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() を使う側にとって限りなく使いづらい、と思いませんか?
その辺が策定理由かと。
> 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() を使う側にとって限りなく使いづらい、と思いませんか?
あまりピンときませんが、「メンバ変数が書き換えられる可能性がある」
ので「使いづらい」のでしょうか?