微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 enum 使用 getter 访问结构成员的函数专业化

如何解决使用 enum 使用 getter 访问结构成员的函数专业化

我有一个枚举和一个结构

enum STORE_ENUM { A_DATA,B_DATA,C_DATA,D_DATA };
struct Store {
   int a;
   char b;
   long c;
   bool d;

}

我想用一个专门的 get 函数来访问它的成员,基本上看起来像这样

T get(STORE_ENUM,store s);

并返回适当的类型,并希望进行静态类型检查。 这在 C++ 中可能吗?

解决方法

是的,这是可能的。 boost PFR 库允许一些与您设想的非常相似的东西,例如:

auto& x = boost::pfr::get<B_DATA>(s);

请参阅教程 here

,

使用 C++17,您可以执行以下操作

#include <iostream>

enum struct STORE_ENUM { A_DATA,B_DATA,C_DATA,D_DATA };
struct Store {
   int a;
   char b;
   long c;
   bool d;

};

template<STORE_ENUM storeEnum>
auto get(Store const & s){
    if constexpr (storeEnum == STORE_ENUM::A_DATA) return s.a;
    if constexpr (storeEnum == STORE_ENUM::B_DATA) return s.b;
    if constexpr (storeEnum == STORE_ENUM::C_DATA) return s.c;
    if constexpr (storeEnum == STORE_ENUM::D_DATA) return s.d;
}
int main(){
    auto store = Store{ 0,'a',4l,true};
    std::cout << get<STORE_ENUM::A_DATA>( store) << "\n";
    std::cout << get<STORE_ENUM::B_DATA>( store) << "\n";
    std::cout << get<STORE_ENUM::C_DATA>( store) << "\n";
    std::cout << get<STORE_ENUM::D_DATA>( store) << "\n";
}

https://godbolt.org/z/1vffh3

,

在我的解决方案中,我们不需要枚举。它使用模板。

#include <iostream>
#include <type_traits>

struct Store
{
    int a;
    char b;
    long c;
    bool d;

    Store() //Default constructor
    {
        a = 0;
        b = 0;
        c = 0;
        d = false;
    }

    Store(int a,char b,long c,bool d) //Constructor. Custom values.
    {
        this->a = a;
        this->b = b;
        this->c = c;
        this->d = d;
    }

    template <typename T = int,typename = typename std::enable_if<std::is_same<T,int>::value ||
                                                     std::is_same<T,char>::value ||
                                                     std::is_same<T,long>::value ||
                                                     std::is_same<T,bool>::value,void>::type>
    T GetData()
    {
        if (std::is_same<T,char>::value)
        {
            return b;
        }
        if (std::is_same<T,long>::value)
        {
            return c;
        }
        if (std::is_same<T,bool>::value)
        {
            return d;
        }
        return a;
    }
};

int main()
{
    Store store { 63,'@',65,true };
    std::cout << store.GetData() << std::endl;
    std::cout << store.GetData<>() << std::endl;
    std::cout << store.GetData<int>() << std::endl;
    std::cout << store.GetData<char>() << std::endl;
    std::cout << store.GetData<long>() << std::endl;
    std::cout << std::boolalpha << store.GetData<bool>() << std::endl;
}

输出

63
63
63
@
65
true

编译 clang++ ./main.cpp -std=c++11g++ ./main.cpp -std=c++11

https://repl.it/@JomaCorpFX/FunctionSpecialization#main.cpp 中检查/运行此代码

,

std::tuple 基本上就是这样做的,你的类型基本上是一个元组。所以简单快速的方法就是重用std::tuple的机器。

中可能如下所示:

template<STORE_ENUM e>
auto get( Store s ){
  return std::get<(unsigned)e>(std::make_tuple(s.a,s.b,s.c,s.d));
}
template<STORE_ENUM e,class T>
void set( Store& s,T t ){
  std::get<(unsigned)e>(std::tie(s.a,s.d))=t;
}

这是 ,但 的缺失位很简单:

template<STORE_ENUM e>
using store_type = typename std::tuple_element<(unsigned)e,std::tuple<int,char,long,bool>>::type;

template<STORE_ENUM e>
store_type<e> get( Store s ) {
  return std::get<(unsigned)e>(std::make_tuple(s.a,s.d));
}

template<STORE_ENUM e>
void set( Store& s,store_type<e> v ){
  std::get<(unsigned)e>(std::tie(s.a,s.d))=v;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。