che*_*erd 5 c++ templates member-variables
考虑以下两个类:
class LunchBox
{
public:
std::vector<Apple> m_apples;
};
Run Code Online (Sandbox Code Playgroud)
和
class ClassRoom
{
public:
std::vector<Student> m_students;
};
Run Code Online (Sandbox Code Playgroud)
这些类是相似的,因为它们都包含对象的成员变量向量; 然而,它们是不相似的,因为向量的对象是不同的,并且成员变量具有不同的名称.
我想写一个模板,它接受LunchBox
或ClassRoom
作为模板参数(或其他一些参数)和相同类型的现有对象(类似于a 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);
Run Code Online (Sandbox Code Playgroud)
我想这样做而不为每个类编写模板特化(这可能需要指定成员变量以某种方式操作).最好,我不想修改LunchBox
或ClassRoom
类.写这样的模板有可能吗?
您可以最小化必须为每个类编写的代码量 - 它不必是模板专门化,也不必是整个类.
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);
Run Code Online (Sandbox Code Playgroud)
理想情况下,简单的辅助函数重载应该与类型在同一名称空间中,以使依赖于参数的查找工作(也称为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);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1537 次 |
最近记录: |