c++ - 如何在不借助 std::function 的情况下存储函数对象?

标签 c++ templates c++11 lambda

我正在尝试制作一个通用容器来容纳对象及其位置:

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);
    ...
} ;

但是如果用户的对象位置 getter 没有被调用怎么办 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_;
    } ;
    

我可以使用 object generator idiom使使用 lambdas 成为可能:

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随心所欲。这种方法有太多问题,我什至不知道从哪里开始。

请问还有其他方法吗?我错过了什么吗?欢迎任何指导!

编辑:

关于解决方案 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());

...但是容器从业务对象生成 key 的设计通常运行不佳,因为查找对象需要做一个虚拟的,这可能很昂贵。

关于c++ - 如何在不借助 std::function 的情况下存储函数对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34978402/

相关文章:

c# - 在哪里可以找到默认的 wpf 图表模板?

c++ - 创建嵌套类的实例时,是否也创建了嵌套类的实例?

c++ - unordered_set 非 const 迭代器

c++ - 如何放置线程数组的动态大小

c++ - STL map 如何知道该 map 包含给定元素?

C++ 没有用于 list::erase 的匹配函数

c++ - C++ boost lambda 和 == 运算符的问题

c++ - 将共享指针设置为空

c++ - MSVS 2015 : vector<bool> has no 'data' member

c++ - 如何通过类型推导过滤可变参数模板包?