【发布时间】:2018-09-02 21:39:47
【问题描述】:
我有一个接受输入的类,有时我想通过分配一个变量来设置该输入,而在其他时候我希望该类调用一个函数来获取它的输入。
在过去,我只是使用 std::function<T()> 作为输入,并设置一个 lambda 来返回某个外部变量的值,但我正试图摆脱对 std::function 的过度使用。于是我想出了std::variant<T, std::function<T()>>:
template <typename T>
using functionable = std::variant<T, std::function<T()>>;
// return the T or the result of the T() from the variant
template <typename T>
T get(const functionable<T>& f) {
if (f.index() == 0)
return std::get<0>(f);
else
return std::get<1>(f)();
}
这样实现的:
class SomeClass {
private:
functionable<int> input_{0};
public:
SomeClass(const functionable<int>& input) : input_{input} {}
SomeClass& operator=(const functionable<int>& rhs) {
input_ = rhs;
return *this;
}
void print() { std::cout << get(input_) << '\n'; }
并因此灵活使用:
SomeClass foo {42}; // init with assigned value
foo.print();
foo = 101; // overwrite assigned value
foo.print();
bool a{true};
// replace input value with input lambda
foo { [this]{if(a) return 10; else return 20;} };
foo.print();
a = !a; // useful if input predicates change
foo.print();
foo = 101; // replace std::function input with assigned int
foo.print();
与仅使用 std::function<T()> 输入和使用 foo = []{return 42;} 固定输入值相比,这是否有所改进?
另一种方法是为分配的输入和调用的输入创建单独的子类,但是当有多个输入时会导致组合爆炸。我还缺少其他选择吗?
【问题讨论】:
标签: c++ stl std-function std-variant