簡體   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