Jon*_*Mee 11 c++ conditional templates case-statement nested-if
所以我有这个非常难看的代码:
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);}
Run Code Online (Sandbox Code Playgroud)
我正在使用嵌套的conditional_ts来创建一个case语句.有什么东西可以更优雅地完成这个或者我需要做出我自己的模板化案例陈述吗?
注意:我实际上意识到这种用法reinterpret_cast很糟糕:为什么不为同尺寸类型之间的强制转换重新解释强制copy_n?
Dan*_*Dan 10
我不得不做一次这样的事情,所以我写了一个小包装器来整齐地实现结果.您可以按如下方式使用它(请参阅此处进行测试)
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){ ... }
Run Code Online (Sandbox Code Playgroud)
在幕后它几乎完成了你已经拥有的东西,但通过包装它我们保持它(更多)可读性.T如果需要,还有一个允许您在类型上切换direclty的版本.
编辑:@ Deduplicator的建议在这里是它背后的代码
#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!");
};
Run Code Online (Sandbox Code Playgroud)
switch 语句的模板版本是专用模板。
template<size_t n> struct matching_type;
template<> struct matching_type<sizeof(char)> { typedef char type; };
template<> struct matching_type<sizeof(short)> { typedef short type; };
template<> struct matching_type<sizeof(int)> { typedef int type; };
template<> struct matching_type<sizeof(long)> { typedef long type; };
template<> struct matching_type<sizeof(long long)> { typedef long long type; };
template<typename T>
matching_type<sizeof(T)>::type foo(T bar)
{
return reinterpret_cast<decltype(foo(bar))>(bar);
}
Run Code Online (Sandbox Code Playgroud)