是否有可能获得一个模板来使用该类的类和成员函数?

时间:2015-02-25 17:02:40

标签: c++ c++11 visual-c++

我正在尝试为使用大小函数和项索引函数的泛型对象创建for_each函数。但是我的语法有些困难。

这是我到目前为止(从第128行开始):

class base1
{
protected:
    std::vector<int> items;
public:
    base1()
        : items({1,2,3})
    {
    }

    int GetCount() const
    {
    }
};

class base2 : public base1
{
public:
    base2()
        : base1()
    {
    }

    int GetItem(int i) const
    {
        return items[i];
    }
};

class derived : public base2
{
public:
    derived()
        : base2()
    {
    }
};

template <typename CONTAINER, typename CONTAINER_BASE1, typename CONTAINER_BASE2, typename SIZE, typename CONTAINED, typename FUNC>
void for_each(CONTAINER* container, SIZE (CONTAINER_BASE1::*GetSize)() const, CONTAINED (CONTAINER_BASE2::*GetItem)(SIZE) const, FUNC& body)
{
    for (SIZE i = 0; i < container->*GetSize(); ++i)
    {
        body(container->*GetItem(i));
    }
}

void fn()
{
    derived x;
    for_each(&x, &derived::GetCount, &derived::GetItem, [](int i){
        ++i;
    });
}

现在,我从VC ++ 2013收到错误说明:

1>d:\projects\test\test.cpp(169): error C2064: term does not evaluate to a function taking 0 arguments
1>          d:\projects\test\test.cpp(180) : see reference to function template instantiation 'void for_each<derived,base1,base2,int,int,fn::<lambda_862ea397905775f7e094cde6fe9b462c>>(CONTAINER *,SIZE (__thiscall base1::* )(void) const,CONTAINED (__thiscall base2::* )(SIZE) const,FUNC &)' being compiled
1>          with
1>          [
1>              CONTAINER=derived
1>  ,            SIZE=int
1>  ,            CONTAINED=int
1>  ,            FUNC=fn::<lambda_862ea397905775f7e094cde6fe9b462c>
1>          ]
1>d:\projects\test\test.cpp(171): error C2064: term does not evaluate to a function taking 1 arguments

关于问题是什么的任何想法?

1 个答案:

答案 0 :(得分:6)

你有两个错误。你通过非const左值引用 - FUNC& body来获取仿函数 - 它不像lambda那样绑定到临时值;这是由一个可怕的MSVC扩展隐藏,允许这样的绑定。你应该通过值接受函数对象(它通常由标准库完成的方式),通过const lvalue引用(如果复制很昂贵和/或身份很重要),或通过转发引用(如果身份很重要并且{{ 1}}可以是非operator())。

其次是运营商优先权。后缀函数调用运算符的优先级高于const.*->*container->*GetSize();你想要container->*(GetSize())

我也不确定这个设计。提供统一的界面可能更好,而且只需使用(container->*GetSize)()container.size(),而不是使用这种折弯的指针到成员函数系统。