有没有类似模板化案例陈述的东西

所以我有这个非常丑陋的代码:

So I have this really ugly code:

template <typename T>
std::conditional_t<sizeof(T) == sizeof(char),
                   char,
                   conditional_t<sizeof(T) == sizeof(short),
                                 short,
                                 conditional_t<sizeof(T) == sizeof(long),
                                               long,
                                               enable_if_t<sizeof(T) == sizeof(long long),
                                                           long long>>>> foo(T bar){return reinterpret_cast<decltype(foo(bar))>(bar);}

我正在使用嵌套的 conditional_ts 来进行各种案例陈述.有没有什么可以更优雅地完成此任务,还是我需要编写自己的模板化案例陈述?

I'm using nested conditional_ts to make a case-statement of sorts. Is there something out there that accomplishes this more elegantly or do I need to cook up my own templatized-case-statement?

注意:我实际上知道 reinterpret_cast 的这种使用是不好的:为什么不 reinterpret_cast Force copy_n for Casts between-same-sized-types/28697985?子>

Note: I am actually aware that this use of reinterpret_cast is bad: Why Doesn't reinterpret_cast Force copy_n for Casts between Same-Sized Types?

推荐答案

我不得不这样做一次,所以我写了一个 small wrapper 整齐地实现结果.您可以按如下方式使用它(请参阅此处进行测试)

I had to do something like this once so I wrote a small wrapper to acheive the result neatly. You could use it as follows (see here for a test)

template<class T>
typename static_switch<sizeof(T)
            ,int // default case
            ,static_case<sizeof(char),char>
            ,static_case<sizeof(short),short>
            ,static_case<sizeof(long),long>
            >::type foo(T bar){ ... }

在幕后,它几乎可以完成您已经拥有的功能,但通过包装它,我们可以保持(更多)可读性.如果需要,还有一个版本允许您直接切换类型 T.

Behind the scenes it pretty much does what you already have but by wrapping it we keep it (more) readable. There is also a version to allow you to switch direclty on the type T if you needed that.

@Deduplicator 的建议是它背后的代码

At @Deduplicator's suggestion here is the code behind it

#include <type_traits>  

/* 
 * Select a type based on the value of a compile-time constant such as a 
 * constexpr or #define using static_switch. 
 */ 

template<int I,class T> 
struct static_case { 
    static constexpr int value = I; 
    using type = T; 
}; 

template<int I, class DefaultType, class Case1, class... OtherCases> 
struct static_switch{ 
    using type = typename std::conditional< I==Case1::value ,  
                    typename Case1::type, 
                    typename static_switch<I,DefaultType,OtherCases...>::type 
                     >::type; 
}; 

struct fail_on_default {};

template<int I, class DefaultType, class LastCase> 
struct static_switch<I,DefaultType,LastCase> { 
    using type = typename std::conditional< I==LastCase::value ,  
                    typename LastCase::type, 
                    DefaultType 
                     >::type; 

    static_assert(!(std::is_same<type, fail_on_default>::value),
                  "Default case reached in static_switch!");
}; 

相关文章