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