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

时间:2022-08-26 18:52:31

I'm trying to make a for_each function for a generic object that uses an size function and an item index function. But I'm having some difficulty with the syntax.

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

This is what I have so far (starting at line 128):

这是我到目前为止(从第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;
    });
}

Right now, I get an error from VC++ 2013 stating:

现在,我从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

Any ideas as to what the problem is?

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

1 个解决方案

#1


6  

You have two bugs. You take the functor by non-const lvalue reference - FUNC& body - which doesn't bind to a temporary like a lambda; this was hidden by a terrible MSVC extension that allows such bindings. You should accept the function object by value (the way it is usually done by the standard library), by const lvalue reference (if copying is expensive and/or identity is important), or by forwarding reference (if identity is important and operator() can be non-const).

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

Second is operator precedence. The postfix function call operator has higher precedence than .* and ->*. container->*GetSize() is container->*(GetSize()); you want (container->*GetSize)().

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

I'm also not sure about this design. It's probably better to provide a uniform interface, and simply do, e.g., container.size() and container.at(i) than using this tortured system of pointer-to-member-functions.

我也不确定这个设计。提供一个统一的接口可能更好,并且只需使用例如container.size()和container.at(i),而不是使用这种折叠的指针到成员函数系统。

#1


6  

You have two bugs. You take the functor by non-const lvalue reference - FUNC& body - which doesn't bind to a temporary like a lambda; this was hidden by a terrible MSVC extension that allows such bindings. You should accept the function object by value (the way it is usually done by the standard library), by const lvalue reference (if copying is expensive and/or identity is important), or by forwarding reference (if identity is important and operator() can be non-const).

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

Second is operator precedence. The postfix function call operator has higher precedence than .* and ->*. container->*GetSize() is container->*(GetSize()); you want (container->*GetSize)().

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

I'm also not sure about this design. It's probably better to provide a uniform interface, and simply do, e.g., container.size() and container.at(i) than using this tortured system of pointer-to-member-functions.

我也不确定这个设计。提供一个统一的接口可能更好,并且只需使用例如container.size()和container.at(i),而不是使用这种折叠的指针到成员函数系统。