C++ 使用std::variant<;T、 std::函数<;T()>&燃气轮机;作为灵活的输入,而不是子类化

C++ 使用std::variant<;T、 std::函数<;T()>&燃气轮机;作为灵活的输入,而不是子类化,c++,stl,std-function,std-variant,C++,Stl,Std Function,Std Variant,我有一个类,它接受一个输入,有时我想通过赋值一个变量来设置这个输入,有时我想让这个类调用一个函数来获取它的输入 在过去,我只会使用std::function作为输入,并设置lambda以返回某个外部变量的值,但我正在尝试停止过度使用std::function。所以我想出了std::variant: 这是否比单独使用std::function作为输入和使用foo=[]{return 42;}作为固定输入值有所改进 另一种方法是为分配的vs(称为输入)创建单独的子类,但当有多个输入时,会导致组合爆炸

我有一个类,它接受一个输入,有时我想通过赋值一个变量来设置这个输入,有时我想让这个类调用一个函数来获取它的输入

在过去,我只会使用
std::function
作为输入,并设置lambda以返回某个外部变量的值,但我正在尝试停止过度使用
std::function
。所以我想出了
std::variant

这是否比单独使用
std::function
作为输入和使用
foo=[]{return 42;}
作为固定输入值有所改进


另一种方法是为分配的vs(称为输入)创建单独的子类,但当有多个输入时,会导致组合爆炸。我还缺少其他选择吗?

从数学上讲,常数函数只是另一个函数。在这个C++例子中,似乎没有动机来把常量函数当作特殊情况来处理。性能可能大致相同,除非大部分输入是常量

此外,此
functionable
不能与
std::generate
一起使用,而包装常量的
std::function
可以。当然,通过将
functionable
封装在自己的类中或在另一个lambda中捕获一个类,这是可以修复的。但当简单的解决方案可以解决问题时,这只会增加复杂性

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