[英]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种方法,但都不理想:
std::function<const Vector& (const T& t)>
成员添加到Container
。 这是一个干净的C ++解决方案,但是该函数将被非常频繁地调用,并且可能导致性能显着下降。
将仿函数对象添加到容器中:
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。
#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.