繁体   English   中英

C++模板元编程嵌套switch语句

[英]C++ template metaprogramming nested switch statement

假设我有一个像这样的联合类型(变体类型)(仅为演示目的而简化)

enum class Type : uint32_t
{
  Unknown = 0,
  Int64 = 1,
  UInt64 = 2,
  Double = 3
};

struct Value
{
  Type dtype;
  union
  {
    int64_t i;
    uint64_t u;
    double d;
  };
}

我打算将这个值分派给这样的不同函数(实际上是 function 对象,但再次简化......),

template<typename... T> auto eval(const T&... t)
{
   // ...
}

它需要一个参数包,或更简单的参数包,例如:

template<typename T1, typename T2> auto sum(const T1& a, const T2& b)
{
   return a+b;
}

一般来说,我需要一个具有以下结构的 switch 语句:

  switch (o1.dtype)
  {
    case Type::Int64:
      switch (o2.dtype)
      {
        case Type::Int64:
          F(o1.i, o2.i);
        case Type::Double:
          F(o2.i, o2.d);
        //...
      }
      break;
    case Type::Double
      //...
      

对于调用具有 2 个参数的仿函数的情况。 但对于 3 个参数的情况,情况会变得更糟......

有没有办法通过元编程来概括它? 理想情况下,我将只有一个 switch 语句,并生成所有嵌套的语句。

您可以制作一个可变参数模板 function ,它在第一个参数上进行switch并使用 rest 和 lambda 调用自身类型:

template<typename F, typename... T>
// decltype(auto) is used to deduce the return type from F, throughout
decltype(auto) apply_func(F f, const Value& v, T&&... vs) { // can't say "any number of arguments, all Values", so say "any arguments of any type" and just convert them to Value later
    switch (v.dtype) {
    case Type::Int64: // bind first argument of f to chosen variant of v, then apply new function (with one less argument) to remaining Values
        return apply_func(
            [&](const auto&... args) -> decltype(auto) {
                return f(v.i, args...);
            }, std::forward<T>(vs)...
        );
    case Type::UInt64:
        return apply_func(
            [&](const auto&... args) -> decltype(auto) {
                return f(v.u, args...);
            }, std::forward<T>(vs)...
        );
    case Type::Double:
        return apply_func(
            [&](const auto&... args) -> decltype(auto) {
                return f(v.d, args...);
            }, std::forward<T>(vs)...
        );
    default: throw std::invalid_argument("Unknown dtype");
    }
}

// final overload, when all arguments have been switched on and the chosen variants have been saved into f
template<typename F>
decltype(auto) apply_func(F f) {
    return f();
}

神栓演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM