[英]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.