C++ 我可以定义从std::function到std::shared的隐式转换吗;MyClass>;?
我有一个类作为谓词从列表中选择值C++ 我可以定义从std::function到std::shared的隐式转换吗;MyClass>;?,c++,c++11,std,implicit-conversion,C++,C++11,Std,Implicit Conversion,我有一个类作为谓词从列表中选择值 class Predicate { public: // In this example, I am using QString as value type // this is not what happens in actual code, where more complex data is being validated virtual bool evaluate(const QString& val) const = 0
class Predicate {
public:
// In this example, I am using QString as value type
// this is not what happens in actual code, where more complex data is being validated
virtual bool evaluate(const QString& val) const = 0;
};
最初,我使用lambda函数,但这会产生大量重复的垃圾代码。因此,我想使用使用继承的谓词类。例如:
class PredicateMaxLength: public RowPredicate {
public:
PredicateMaxLength(const int max) : maxLength(max) {}
virtual bool evaluate(const QString& val) const {return val.length()<maxLength;}
protected:
const int maxLength;
};
这样做的恶劣影响是,无论何时使用lambda,都必须将其包装到PredicateLambda
构造函数中:
myObject.deleteItems(std::make_shared<PredicateLambda>([]->bool{ ... lambda code ... }));
myObject.deleteItems(std::make_shared([]->bool{…lambda code…}));
这太难看了。我有两个选择:
- 对于每个接受谓词的函数,都有一个重载来执行上面所示的转换。这与头文件中的方法数相同
- 从
隐式转换为std::function
,执行以下操作:std::shared\u ptr
std::shared_ptr<Predicate> magicImplicitConversion(const StdPredicateLambda& lambdaFn) { return std::make_shared<PredicateLambda>(lambdaFn); }
std::共享\ptr magicImplicitConversion(const stdprededicatelambda和lambdaFn){ 返回标准::使_共享(lambdaFn); }
我来这里是想问第二种选择是否可行。如果是,是否有任何风险?如果您不想使用
模板
不公开代码,您可以使用std::function
:
class SomeDataObject {
// Removes all values that satisfy the given predicate
int removeValues(std::function<bool(const QString&)> pred);
};
类SomeDataObject{
//删除满足给定谓词的所有值
int-removeValues(std::函数pred);
};
你的谓词呢
class PredicateMaxLength {
public:
explicit PredicateMaxLength(int max) : maxLength(max) {}
bool operator ()(const QString& val) const {return val.length()<maxLength;}
protected:
int maxLength;
};
类谓词MaxLength{
公众:
显式谓词maxLength(int max):maxLength(max){}
bool操作符()(const QString&val)const{return val.length()您想要多态性,并且不想使用模板样式的头lambdas。并且您希望能够有一些默认情况
正确的答案是扔掉你的谓词
类
使用使用谓词=std::function;
接下来,请注意,您的谓词
子类型基本上是带有一些额外状态的谓词的工厂(构造函数是工厂)
对于std::function
,这样的工厂只是返回谓词的函数
using Predicate = std::function<bool(const QString&)>;
Predicate PredicateMaxLength(int max) {
return [max](QString const& str){ return val.length()<max; }
}
使用Predicate=std::function;
谓词谓词MaxLength(int max){
return[max](QString const&str){return val.length()为什么要使用shared\u ptr
而不是const&
?在所有情况下,如果可以的话,您都应该将removeValues
设置为模板化方法。@Holt我需要继承才能正常工作。按值传递时,对象似乎会丢失重载函数,这是调用的。是的,但const&
不是按值传递,而是按r传递Engess,它与虚拟函数很好地结合,但是实际上,你会遇到同样的问题,看看我对C++解决方案的答案。你能描述一下“重复垃圾代码”吗??只是在执行评估?@Holt不知道其他人如何告诉你,只是想说,你删除了你的答案真是太遗憾了。这并不完全是我需要/想要的,但其他人可能会觉得它有用。()
运算符隐式转换为std::Function
?虚拟方法仍然有效吗?目前,我有()
在最顶层的谓词中实现。请看:Functor应该可以用给定的参数调用。对于虚拟部分,您必须通过std::ref
传递Functor以避免切片。@Jarod42如果您在调用期间构造谓词(就像您所做的那样),没有切片,因为F
的推断类型将直接是子级的类型。我尝试了此操作,但它拒绝从谓词中强制转换或构造std::function
:@TomášZato谓词
未实现操作符()
。请参阅。
class PredicateMaxLength {
public:
explicit PredicateMaxLength(int max) : maxLength(max) {}
bool operator ()(const QString& val) const {return val.length()<maxLength;}
protected:
int maxLength;
};
SomeDataObject someDataObject;
someDataObject.removeValues(PredicateMaxLength(42));
someDataObject.removeValues([](const QString& s) { return s.size() < 42; });
using Predicate = std::function<bool(const QString&)>;
Predicate PredicateMaxLength(int max) {
return [max](QString const& str){ return val.length()<max; }
}