我有一個類作爲謂詞從列表中選擇值。我可以定義從std :: function到std :: shared_ptr的隱式轉換<MyClass>?
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_;
};
這個討厭的效果是,每當使用拉姆達,它必須被包裹成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); }
我來這裏問了第二個選項是否是可能的。如果是,它是否有風險?
爲什麼使用'shared_ptr'而不是'const'?在所有情況下,如果你可以使'removeValues'成爲模板化的方法。 – Holt
@Holt我需要繼承才能正常工作。當通過值傳遞時,對象似乎失去了重載函數,稱爲[對象切片](http://stackoverflow.com/a/274634/607407)。 –
是的,但'const&'不是*傳值*,它是*通過引用*,並且它與虛函數很好地協作。但實際上,您會遇到同樣的問題,請參閱我的答案以獲取真正的C++解決方案。 – Holt