3

次のファンクターとその部分的な特殊化があります

template    <class _T, typename _Return = void, typename _Arg = void>
struct  Caller
{
    typedef _Return(_T::*Method)(_Arg);

    Caller(Method pm, _Arg a)
    :   _pMethod(pm),
        _arg(a)
    {}

    _Return operator()(_T& obj)
    {
        return (obj.*_pMethod)(_arg);
    }

    Method  _pMethod;
    _Arg    _arg;
};

template    <class _T, typename _Return>
struct  Caller<_T, _Return, void>
{
    typedef _Return(_T::*Method)();

    Caller(Method pm)
    :   _pMethod(pm)
    {}

    _Return operator()(_T& obj)
    {
        return (obj.*_pMethod)();
    }

    Method  _pMethod;
};

私はそれを次のように使用しようとしています:

struct Foo
{
    void Bar() const
    {
         void(0);
    }
};

// ...

std::list<Foo> foos;
const std::list<Foo> &rFoos(foos);
std::for_each(rFoos.begin(), rFoos.end(), Caller<const Foo>(&Foo::Bar));

コードの最後の行については、これを取得しています (IDE は発信者を取得します)。

エラー C2440: '' : 'void (__thiscall Foo::* )(void) const' から 'Caller<_T>' 1> に 1> [ 1> _T=const Foo 1> ] 1> で変換できません。ソース型を取得するか、コンストラクターのオーバーロードの解決があいまいでした

このコードは g++ 環境で機能します。(関数がconstオブジェクトCaller<Foo>(&Foo::Bar)でのみ呼び出されるため、私が g++ で文句を言うのは理にかなっています)。

ファンクターにoperator()(const _T& obj)/種類を追加するなど、さまざまなことを試しましたが、役に立ちませんでした。operator()(const _T& obj) const

これは、コンパイラによって受け入れられます。

struct Foo
{
    void Bar()
    {
         void(0);
    }
};

// ...

std::list<Foo> foos;
const std::list<Foo> &rFoos(foos);
std::for_each(rFoos.begin(), rFoos.end(), Caller<Foo>(&Foo::Bar));

私は何を間違っていますか?Visual C++ で const メンバー関数に対してファンクター テンプレートを機能させるにはどうすればよいですか?

4

2 に答える 2

1

_Tin の constness はinの constness of automatically に MSVC でCaller反映されていないと思います(どちらかと言えば、あなたが言及した GCC の動作は奇妙に感じます)。の定数にの 定数を反映させたい場合は、次のような補助クラスを用意し、 の定数に応じて適切なシグネチャを選択してみてはいかがでしょうか。thisMethod
_TthisSelect_TypeT_

template <class C, class T, class Const_T>
struct Select_Type { typedef T type; };

template <class C, class T, class Const_T>
struct Select_Type<C const, T, Const_T> { typedef Const_T type; };

template    <class _T, typename _Return>
struct  Caller<_T, _Return, void>
{
    typedef typename Select_Type<
        _T, _Return(_T::*)(), _Return(_T::*)()const >::type Method;
    ....
于 2011-07-15T16:04:07.167 に答える
1

operator()関数は const である必要があります (ファンクター自体を変更することはありませんが、新しい関数セットが必要になるとは思いません) 。

また、アンダースコアと大文字で始まるすべてのタイプは、実装の標準によって予約されていることに注意してください。

于 2011-07-15T15:23:46.270 に答える