想象一下,我们有一个模板类。像这样
template<typename T>
class MyTemplateClass {
private:
T _v1, _v2;
public:
MyTemplateClass(T v1, T v2)
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _v1 > _v2;
}
};
//usage
MyTemplateClass<int> test(1, 2);
std::cout << test.Act() << std::endl;
现在我们想将函子对象/函数指针/ lambda传递给他的构造函数,以便我们可以使用它。
我已经尝试过类似的操作,但是遇到运行时错误
template<typename T, typename F>
class MyTemplateClass {
private:
T _v1, _v2;
const F& _func;
public:
MyTemplateClass(T v1, T v2, F functor)
:_func(functor)
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _func(_v1, _v2);
}
};
bool isGreater(int a, int b)
{
return a > b;
}
//later
MyTemplateClass<int, std::function<bool(int, int)>> test(1, 2, isGreater);
std::cout << test.Act() << std::endl;
那么我如何实现此功能?有什么方法可以在不使用std :: function且不为functor对象传递typename的情况下使其工作? 我想用这种方式
MyTemplateClass<int> test(1, 2, isGreater);
答案 0 :(得分:2)
不,由于引用了临时对象(functor
),因此无法正常工作
const F& _func;
public:
MyTemplateClass(T v1, T v2, F functor)
:_func(functor)
存储对象:
F _func;
public:
MyTemplateClass(T v1, T v2, F functor)
:_func(std::move(functor))
或者在某些情况下,您知道对象的生存期,请将其作为const&:
传递MyTemplateClass(T v1, T v2, const F& functor)
答案 1 :(得分:2)
我已经尝试过类似的操作,但是遇到运行时错误
正如Matthieu Brucher指出的their answer一样,您不能将_func
存储为引用,因为将引用绑定到的对象会在构造函数调用结束时死亡。更改为按值存储_func
将解决此问题。
有什么方法可以在不使用std :: function且不为functor对象传递typename的情况下使其工作?我想用这种方式
MyTemplateClass<int> test(1, 2, isGreater);
这实际上很容易做到。您仍然必须使用std::function
作为存储类型和构造函数参数类型,但不必指定它。利用type alias,我们可以根据类成员的类型指定谓词类型。这给了我们
using predicate = std::function<bool(T, T)>;
,将其添加到类中后,我们可以将其修改为
template<typename T>
class MyTemplateClass {
public:
using predicate = std::function<bool(T, T)>;
MyTemplateClass(T v1, T v2, predicate functor)
:_func(std::move(functor))
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _func(_v1, _v2);
}
private:
T _v1, _v2;
predicate _func;
};
现在可以像这样使用
int main()
{
MyTemplateClass<int> test(1, 2, isGreater);
std::cout << test.Act() << std::endl;
}