假设我有以下模板。
template<typename T>
class MyClass
{
public:
.............
private:
T _data;
}
当我使用它时,T始终是一个结构(仅限数据)。例如,
struct ST1{
int a;
int b;
};
struct ST2{
int a1;
int b1;
int c1;
}
对于MyClass的特定实例,例如MyClass<struct ST1> myinstance
,我想访问myinstance.data.a
或myinstance.data.b
。我能想到的一种通用方法是在MyClass中定义方法,如
void MyClass::write(T const &){ _data = T;}
T MyClass::read(){return _data;}
但问题是,对于每次读写,我都需要创建一个结构实例,即使我只访问_data
的一小部分。
由于
答案 0 :(得分:1)
怎么样......
const T& MyClass::GetData() const { return _data; }
T& MyClass::GetData() { return _data; }
然后你就可以......
myClass.GetData().a = 17;
你也可以公开_data
。
答案 1 :(得分:1)
你要做的第一件事就是考虑公开_data
。如果它只是数据,并且它没有活动,并且暴露其二进制布局不是问题,那么这是有效的。
如果您希望能够“挂机”访问_data
(例如,使用互斥锁,或远程获取/设置某些信息),并且您可以访问C ++ 11 lambdas,则此模式可以是有用:
template<typename Lambda>
auto Data( Lambda&& closure )->decltype( closure(_data) ) {
// do pre-processing
auto retval = closure(_data);
// do post-processing
return retval;
}
template<typename Lambda>
auto Data( Lambda&& closure ) const->decltype( closure(_data) ) {
// do pre-processing
auto retval = closure(_data);
// do post-processing
return retval;
}
你会像这样使用:
int main() {
MyClass<Foo> instance;
int x = instance.Data( [&]( Foo const& foo ) {
return foo.x;
});
instance.Data( [&]( Foo& foo ) {
foo.y = 3;
});
}
可让您操纵数据“内部”包裹MyClass
的代码。
在C ++ 14 auto
lambdas出现之前,这有点尴尬,因为你必须重复Foo
的类型。
这种风格的好处是MyClass
甚至不必存储Foo
的实例!它可以按需生成Foo
,然后从用户更改的内容中回读。