bind1st と mem_fun_ref

[戻る]
mkz 2007/01/08(月) 13:42:47
環境は 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 2007/01/09(火) 09:27:26
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 2007/01/09(火) 19:35:56
> 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() を使う側にとって限りなく使いづらい、と思いませんか?

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

古いスレッドには追加発言できません。