c++ - 我可以定义从 std::function 到 std::shared_ptr<MyClass> 的隐式转换吗?

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

最初,我使用了 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;
};

为了允许继承发挥作用,给出的是指针而不是值:

class SomeDataObject {
    // Removes all values that satisfy the given predicate
    int removeValues(const std::shared_ptr<Predicate> pred);
}

现在,在代码不重复的情况下(例如某些特殊情况),我们肯定仍然会使用 lambda。为此,PredicateLambda已创建:

typedef std::function<bool(const QString& val)> StdPredicateLambda;
class PredicateLambda: public Predicate {
public:
    PredicateLambda(const StdPredicateLambda& lambda) : RowPredicate(), callback_(lambda) {}
    virtual bool evaluate(const QString& val) const override {return callback_(val);}
protected:
    const StdPredicateLambda callback_;
};

这样做的恶劣影响是,每当使用 lambda 时,它都必须被包装到 PredicateLambda 中。构造函数:

myObject.deleteItems(std::make_shared<PredicateLambda>([]->bool{ ... lambda code ... }));

这太丑了。我有两个选择:

  • 对于每个接受谓词的函数,都有一个重载来执行上面看到的转换。这会重复头文件中的方法数量
  • std::function<bool(const QString& val)> 进行隐式转换至std::shared_ptr<Predicate>这将执行这个:

    std::shared_ptr<Predicate> magicImplicitConversion(const StdPredicateLambda& lambdaFn) {
        return std::make_shared<PredicateLambda>(lambdaFn);
    }
    

我来这里是想问第二个选项是否可行。如果是的话,有什么风险吗?

最佳答案

如果您不想使用template来不公开代码,您可以使用std::function:

class SomeDataObject {
    // Removes all values that satisfy the given predicate
    int removeValues(std::function<bool(const QString&)> pred);
};

和你的谓词

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

关于c++ - 我可以定义从 std::function 到 std::shared_ptr<MyClass> 的隐式转换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38720332/

相关文章:

C++下标[]运算符重载

c++ - 一旦 writer 在 Reader writer lock 中完成写入,Reader 就不会被唤醒

c++ - std::map 与 lambda 比较器

c++ - std::shared_ptr 和继承

c++ - 使用精度集删除尾随 0 的优雅解决方案

c++ - 最多打印 4 位小数

c++ - 确保指针未被删除

c++ - std::unordered_map 和重复键

c++ - std::move 如何应用于函数返回值?

c++ - 重新定位 vector 的一部分