C++ 在运行时询问变量中的替代项是否满足某个概念

C++ 在运行时询问变量中的替代项是否满足某个概念,c++,variant,c++-concepts,C++,Variant,C++ Concepts,我有以下内容,试图检测变量中的替代概念(本例中为成员函数)。 它冗长且相对丑陋。 有更好的方法吗? 注意,我不想使用继承,也不想使用静态多态性(假设编译时不知道使用了什么引擎) 简单地说,我在寻找if constexpr(只在编译时检查概念)和std::holds_alternative(只检查特定类型是否在variant中,而不检查满足概念的任何类型是否在variant中)的运行时组合 #包括 #包括 结构简单引擎1{ }; 结构简单引擎2{ }; 结构复合引擎1{ 无效减小推力(int pe

我有以下内容,试图检测变量中的替代概念(本例中为成员函数)。 它冗长且相对丑陋。 有更好的方法吗? 注意,我不想使用继承,也不想使用静态多态性(假设编译时不知道使用了什么引擎)

简单地说,我在寻找
if constexpr
(只在编译时检查概念)和
std::holds_alternative
(只检查特定类型是否在
variant
中,而不检查满足概念的任何类型是否在
variant
中)的运行时组合

#包括
#包括
结构简单引擎1{
};
结构简单引擎2{
};
结构复合引擎1{
无效减小推力(int perc){

std::cout如果constexpr
,您可以使用
大大简化访问者:

struct visitor{
  template<typename T>
  void operator()(T& t) {
    if constexpr (has_reduce_thrust<T>::value) {
      t.reduce_thrust(perc);
      reduced_thrust = true;
    }
    else {
      reduced_thrust = false;
    }
  }

  int perc = 0;
  bool reduced_thrust = false;  
};
template <template <class, class... /*SFINAE friendly*/> class TypePred,
          class MatchedFunc, class UnmatchedFunc>
class predicated_visitor {
 public:
  predicated_visitor(MatchedFunc matchedFunc, UnmatchedFunc unmatchedFunc)
      : _matchedFunc(matchedFunc), _unmatchedFunc(unmatchedFunc) {}

  template <typename T>
  void operator()(T& t) {
    if constexpr (TypePred<T>::value)
      _matchedFunc(t);
    else
      _unmatchedFunc(t);
  }

 private:
  MatchedFunc _matchedFunc;
  UnmatchedFunc _unmatchedFunc;
};

template <template <class, class... /*SFINAE friendly*/> class TypePred,
          class F1, class F2>
auto makePredicatedVisitor(F1 f1, F2 f2) {
  return predicated_visitor<TypePred, F1, F2>(f1, f2);
}
结果代码非常好,我觉得:

void reduce_speed(std::variant<simple_engine1, simple_engine2, complex_engine1,
                               complex_engine2>* var_engine) {
  int perc = 47;
  bool reducedThrust = false;

  auto reduceableThrustAction = [perc, &reducedThrust](auto& t) {
    t.reduce_thrust(perc);
    reducedThrust = true;
  };
  auto alternativeAction = [](auto& t) {
  };  // Could explicitly set reduceThrust to false for clarity.

  auto thrust_visitor = makePredicatedVisitor<has_reduce_thrust>(
      reduceableThrustAction, alternativeAction);

  std::visit(thrust_visitor, *var_engine);

  if (reducedThrust) {
    std::cout << "reduced thrust\n";
  } else {
    std::cout << "activating reverse engines\n";
  }
}
void减速(标准::变型*var\u发动机){
int perc=47;
bool reducedThrust=false;
自动可还原推力=[perc,&还原推力](自动和t){
t、 减小推力(perc);
还原推力=真;
};
自动替代动作=[](自动和t){
};//为了清晰起见,可以显式地将reduceThrust设置为false。
自动推力_visitor=makePredicatedVisitor(
可还原反作用、交替作用);
标准::访问(推力访问者,*var引擎);
如果(减少推力){

STD::CuiAUI,概念是一个完全编译的时间。在运行时,你确实需要一些内省来做这件事,而这不是标准C++的一部分。@ ToBySwitt概念作为语言特征是编译时的事情,但即使在运行时类型存在(类型满足概念)。.你真的想在这里使用概念吗?@MaxLanghof,如果它们有助于提高可读性……从我看来,你的答案已经很好了,但如果概念让它变得更好,那就更好了。
void reduce_speed(std::variant<simple_engine1, simple_engine2, complex_engine1,
                               complex_engine2>* var_engine) {
  int perc = 47;
  bool reducedThrust = false;

  auto reduceableThrustAction = [perc, &reducedThrust](auto& t) {
    t.reduce_thrust(perc);
    reducedThrust = true;
  };
  auto alternativeAction = [](auto& t) {
  };  // Could explicitly set reduceThrust to false for clarity.

  auto thrust_visitor = makePredicatedVisitor<has_reduce_thrust>(
      reduceableThrustAction, alternativeAction);

  std::visit(thrust_visitor, *var_engine);

  if (reducedThrust) {
    std::cout << "reduced thrust\n";
  } else {
    std::cout << "activating reverse engines\n";
  }
}