一个仿函数的部分模板特化,它调用传递给它的对象的成员方法

时间:2011-07-15 15:02:18

标签: c++ templates visual-c++ function-pointers partial-specialization

我有以下仿函数及其部分专业化

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'to'Calller&lt; _T&gt;'   1 GT;同   1 GT; [   1 GT; _T = const Foo   1 GT; ]   1 GT;没有构造函数可以采用源类型或构造函数重载   决议是模糊的

此代码适用于g ++环境。 (如果我Caller<Foo>(&Foo::Bar) g ++会抱怨,这是有意义的,因为该函数只会在 const 对象上调用。

我尝试过各种各样的事情,包括将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 ++中使functor模板适用于const成员函数?

2 个答案:

答案 0 :(得分:1)

你的operator()函数需要是const(它们不会改变仿函数本身,但我认为你不需要一组新的函数)。

另请注意,所有以下划线和大写字母开头的类型都由实施标准保留。

答案 1 :(得分:1)

我认为_TCaller的常量并未反映在this中 MSVC中自动Method的常量 (如果有的话,我觉得GCC你提到的行为很奇怪) 如果要在_T的常量中反映this的常量, 如下准备辅助班Select_Type如何,和 根据{{​​1}}?

的常量选择合适的签名
T_