【问题标题】:Return variable type along an enum c++沿枚举c ++返回变量类型
【发布时间】:2018-08-30 13:14:40
【问题描述】:

我需要它用于我正在制作的套接字缓冲区(读取和写入......),这比其他任何东西都更像一个技巧,所以我想知道是否有更好的方法来处理当前的C++ 功能/标准?我很确定。

enum e_Types
{
    Type_64 ,
    Type_32 ,
    Type_16 ,
    Type_8 ,
    Type_ALL
};

template<e_Types Type> constexpr auto _GetVarType()
{
    if constexpr( Type == Type_8 )
        return ( unsigned char* ) 0;
    if constexpr( Type == Type_16 )
        return ( unsigned short* ) 0;
    if constexpr( Type == Type_32 )
        return ( unsigned long* ) 0;
    if constexpr( Type == Type_64 )
        return ( unsigned long long* ) 0;
}

#define GetVarType(type) decltype( _GetVarType<type>() )

例子:

GetVarType( Type_64 ) p64 = malloc(0x1000);

感谢您的回复。

【问题讨论】:

  • cstdint 怎么样?还是e_Types 是必要的?
  • 所有命名空间都保留以_ 和大写字母开头的名称

标签: c++ types enums return constexpr


【解决方案1】:

您可以使用良好的旧显式模板类专业化:

template <e_Types X> struct type_of;
template <>          struct type_of<Type_64> { using type = unsigned long long; };
template <>          struct type_of<Type_32> { using type = unsigned long; };
template <>          struct type_of<Type_16> { using type = unsigned short; };
template <>          struct type_of<Type_8>  { using type = unsigned char; };

template <e_Types X> 
using type_of_t = typename type_of<X>::type;

用法:

type_of_t<Type_64>* p64 = malloc(0x1000);

如果你想沿着基于constexpr 的路线走下去,你可以这样做:

template <typename T> 
struct type_wrapper 
{ 
    using type = T; 
};

template <typename T> 
inline constexpr type_wrapper<T> t{};

template <e_Types X> inline constexpr auto type_of          = t<void>;
template <>          inline constexpr auto type_of<Type_64> = t<unsigned long long>;
template <>          inline constexpr auto type_of<Type_32> = t<unsigned long>;
template <>          inline constexpr auto type_of<Type_16> = t<unsigned short>;
template <>          inline constexpr auto type_of<Type_8>  = t<unsigned char>;

用法:

typename decltype(type_of<Type_64>)::type* p64 = malloc(0x1000);

但我认为这并不比更传统的方法优越。

【讨论】:

  • 谢谢!这正是我所需要的。
  • OP自己的方法也可以,虽然有点丑。只需将宏替换为template&lt;int N&gt; using get_var_type = decltype(_GetVarType&lt;N&gt;());
  • @liliscent:在“它有效”中没问题,但我不明白你为什么要在模板专业化上使用它。
  • @VittorioRomeo 一个可能的优势是if constexpr 对于更复杂的情况可能更具表现力。
  • malloc 的结果中缺少一个演员表:)
【解决方案2】:

基于@liliscent 和@VittorioRomeo 回复/cmets, 我最终这样做了:

template <typename T>
struct Type_Wrapper
{
    using Type = T;
};

template <typename T>
inline constexpr Type_Wrapper<T> _Type{};

template <e_Types Type> inline constexpr auto _GetVarType()
{
    if constexpr( Type == Type_8 )
        return _Type<Byte>;
    else if constexpr( Type == Type_16 )
        return _Type<Word>;
    else if constexpr( Type == Type_32 )
        return _Type<HEX32>;
    else if constexpr( Type == Type_64 )
        return _Type<HEX64>;
    else if constexpr( Type == Type_Pointer )
        return _Type<Pointer>;
    else if constexpr( Type == Type_Size )
        return _Type<size_t>;
    else if constexpr( Type == Type_Array )
        return _Type<Bytes>;
    else
        return _Type<void>;
};

template<e_Types _Type>
using GetVarType_t = typename decltype( _GetVarType<_Type>() );

...

GetVarType_t< Type_64 >::Type Ok = 0;

现在很好,我想摆脱那些 0 因为它看起来不太好。 再次感谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    相关资源
    最近更新 更多