gpt4 book ai didi

c++ - 指向结构/类的递归成员的可变指针序列作为模板参数

转载 作者:可可西里 更新时间:2023-11-01 16:36:42 27 4
gpt4 key购买 nike

我正在为一些模板编程而苦苦挣扎,我希望你能给我一些帮助。我编写了一个 C++11 接口(interface),给定了一些结构,例如:

struct Inner{
double a;
};
struct Outer{
double x, y, z, r;
Inner in;
};

对为指定结构成员定制的真实数据实现getter/setter:

MyData<Outer, double, &Outer::x,
&Outer::y,
&Outer::z,
&Outer::in::a //This one is not working
> state();

Outer foo = state.get();
//...
state.set(foo);

我设法通过以下方式为简单结构实现了这一点:

template <typename T, typename U, U T::* ... Ms>
class MyData{
std::vector<U *> var;
public:
explicit MyData();
void set(T const& var_);
T get() const;
};

template <typename T, typename U, U T::* ... Ms>
MyData<T, U, Ms ... >::Struct():var(sizeof...(Ms))
{
}

template <typename T, typename U, U T::* ... Ms>
void MyData<T, U, Ms ...>::set(T const& var_){
unsigned i = 0;
for ( auto&& d : {Ms ...} ){
*var[i++] = var_.*d;
}
}

template <typename T, typename U, U T::* ... Ms>
T MyData<T, U, Ms ...>::get() const{
T var_;
unsigned i = 0;
for ( auto&& d : {Ms ...} ){
var_.*d = *var[i++];
}
return var_;
}

但是当我传递一个嵌套结构的成员时它失败了。理想情况下,我想实现一个指向成员类型的通用指针,它允许我与多个级别的范围解析兼容。我找到了 this approach ,但我不确定这是否适用于我的问题,或者是否存在一些可供使用的实现。提前致谢!

相关帖子:

Implicit template parameters

Pointer to inner struct

最佳答案

您可以将成员指针包装到结构中以允许更轻松的链接:

template <typename...> struct Accessor;

template <typename T, typename C, T (C::*m)>
struct Accessor<std::integral_constant<T (C::*), m>>
{
const T& get(const C& c) { return c.*m; }
T& get(C& c) { return c.*m; }
};

template <typename T, typename C, T (C::*m), typename ...Ts>
struct Accessor<std::integral_constant<T (C::*), m>, Ts...>
{
auto get(const C& c) -> decltype(Accessor<Ts...>().get(c.*m))
{ return Accessor<Ts...>().get(c.*m); }

auto get(C& c) -> decltype(Accessor<Ts...>().get(c.*m))
{ return Accessor<Ts...>().get(c.*m); }
};

template <typename T, typename U, typename ...Ts>
class MyData
{
std::vector<U> vars{sizeof...(Ts)};

template <std::size_t ... Is>
T get(std::index_sequence<Is...>) const
{
T res;
((Ts{}.get(res) = vars[Is]), ...); // Fold expression C++17
return res;
}
template <std::size_t ... Is>
void set(std::index_sequence<Is...>, T const& t)
{
((vars[Is] = Ts{}.get(t)), ...); // Fold expression C++17
}

public:
MyData() = default;

T get() const { return get(std::index_sequence_for<Ts...>()); }
void set(const T& t) { return set(std::index_sequence_for<Ts...>(), t); }

};

用法类似

template <auto ...ms> // C++17 too
using Member = Accessor<std::integral_constant<decltype(ms), ms>...>;

MyData<Outer, double, Member<&Outer::x>,
Member<&Outer::y>,
Member<&Outer::z>,
Member<&Outer::in, &Inner::a>
> state;

std::index_sequence是 C++14,但可以在 C++11 中实现。
C++17 中的折叠表达式也可以在 C++11 中模拟。
typename <auto> (C++17) 应替换为 typename <typename T, T value> .

Demo

关于c++ - 指向结构/类的递归成员的可变指针序列作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53482238/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com