繁体   English   中英

如何不使用std :: function来存储函数对象?

[英]How to store a function object without resorting to std::function?

我试图做一个通用的容器来容纳对象及其位置:

class Vector;

template <typename T>
class Container 
{
public:
    void insert(const T& t)
    {
        insertAtPosition(t.getPosition() ,t);
    }
private:
    void insertAtPosition(const Vector& v, const T& t);
    ...
} ;

但是,如果用户的对象位置获取器未称为getPosition怎么办?

如何使该容器相对于容器内部获取项目位置的方式通用?

到目前为止,我已经考虑了3种方法,但都不理想:

  1. std::function<const Vector& (const T& t)>成员添加到Container

这是一个干净的C ++解决方案,但是该函数将被非常频繁地调用,并且可能导致性能显着下降。

  1. 将仿函数对象添加到容器中:

     class Vector; template <typename T, typename TGetPosition> class Container { public: Container(TGetPosition getPosition): getPosition_(getPosition){} void insert(const T& t) { insertAtPosition(getPosition_(t) ,t); } private: void insertAtPosition(const Vector& v, const T& t); TGetPosition getPosition_; } ; 

我可以使用对象生成器惯用法来使用lambda:

template <typename T, typename TGetPosition>
Container<T, TGetPosition> makeContainer(TGetPosition getter)
{
    return Container<T, TGetPosition>(getter);
}

...

auto container = makeSimpleContainer<Widget>([](const Widget& w)
    {
        return w.tellMeWhereYourPositionMightBe();
    });

没有性能开销,但是在某些情况下将不可能获得这种容器的类型。 例如,您不能创建将此类容器作为参数的类,因为decltype无效,因为无法在未评估的上下文中使用lambda。

  1. 使用#define GETTER getPosition ,用户只需将getPosition更改getPosition自己喜欢的内容即可。 这种方法有很多问题,我什至不知道从哪里开始。

拜托,还有其他方法吗? 我有什么想念的吗? 任何指导都是最欢迎的!

编辑:

关于解决方案2:我不知道如何获得使用lambda函数创建的容器的类型。 一种方法是:

using TContainer = decltype(makeSimpleContainer<Widget>([](const Widget& w)
    {
        return w.tellMeWhereYourPositionMightBe();
    });)

但这是行不通的,因为不能在未经评估的上下文中使用lambda。

合理可用的选择是期望上下文具有position_for()

template <class T> struct Container {
    size_t insert(T const& x) {
        insertAtPosition(position_for(x), x);
    }
};

Vector const& position_for(const Widget& w) {
    return ...;
}

Container<Widget> c;
c.insert(Widget());

...但是容器在其中从业务对象生成密钥的设计通常不能很好地飞行,因为要查找该对象可能需要做一个虚拟对象,这可能很昂贵。

即使您需要创建一个包含容器的类,您的第二个解决方案似乎仍然可以工作:

template <typename Container>
struct SomeClass {
    SomeClass(const Container &container) : container(container) { }
    Container container;
};


int main()
{
    auto container = makeSimpleContainer<Widget>([](const Widget& w)
        {
            return w.tellMeWhereYourPositionMightBe();
        });
    SomeClass<decltype(container)> test(container);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM