gpt4 book ai didi

c++ - 模板成员变量

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:06:38 25 4
gpt4 key购买 nike

考虑以下两个类:

class LunchBox
{
public:
std::vector<Apple> m_apples;
};

class ClassRoom
{
public:
std::vector<Student> m_students;
};

类的相似之处在于它们都包含对象的成员变量 vector ;但是,它们的不同之处在于 vector 的对象不同并且成员变量具有不同的名称。

我想编写一个模板,将 LunchBoxClassRoom 作为模板参数(或其他一些参数)和相同类型的现有对象(类似到 std::shared_ptr)。该模板将返回一个对象,该对象添加了一个 getNthElement(int i); 成员函数以改进对方法的访问。用法如下:

// lunchBox is a previously initialized LunchBox
// object with apples already pushed into m_apples
auto lunchBoxWithAccessor = MyTemplate<LunchBox>(lunchBox);
auto apple3 = lunchBoxWithAccessor.getNthElement(3);

我想在为每个类编写模板特化的情况下执行此操作(这可能需要指定要以某种方式操作的成员变量)。最好,我不想修改 LunchBoxClassRoom 类。 是否可以编写这样的模板?

最佳答案

您可以最大限度地减少必须为每个类编写的代码量——它不必是模板特化,也不必是整个类。

class LunchBox
{
public:
std::vector<Apple> m_apples;
};

class ClassRoom
{
public:
std::vector<Student> m_students;
};

// you need one function per type, to provide the member name
auto& get_associated_vector( Student& s ) { return s.m_apples; }
auto& get_associated_vector( ClassRoom& r ) { return r.m_students; }

// and then the decorator is generic
template<typename T>
class accessor_decorator
{
T& peer;
public:
auto& getNthElement( int i ) { return get_associated_vector(peer).at(i); }

auto& takeRandomElement( int i ) { ... }

// many more ways to manipulate the associated vector

auto operator->() { return &peer; }
};

LunchBox lunchBox{};
accessor_decorator<LunchBox> lunchBoxWithAccessor{lunchBox};
auto apple3 = lunchBoxWithAccessor.getNthElement(3);

理想情况下,简单的辅助函数重载应该与类型位于相同的命名空间中,以使参数相关的查找工作(也称为 Koenig 查找)。

如果您愿意,也可以在构造时指定成员:

template<typename T, typename TMemberCollection>
struct accessor_decorator
{
// public to make aggregate initialization work
// can be private if constructor is written
T& peer;
TMemberCollection const member;

public:
auto& getNthElement( int i ) { return (peer.*member).at(i); }

auto& takeRandomElement( int i ) { ... }

// many more ways to manipulate the associated vector

auto operator->() { return &peer; }
};

template<typename T, typename TMemberCollection>
auto make_accessor_decorator(T& object, TMemberCollection T::*member)
-> accessor_decorator<T, decltype(member)>
{
return { object, member };
}

LunchBox lunchBox{};
auto lunchBoxWithAccessor = make_accessor_decorator(lunchBox, &LunchBox::m_apples);
auto apple3 = lunchBoxWithAccessor.getNthElement(3);

关于c++ - 模板成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43827582/

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