※ 引述《ofd168 ()》之铭言:
原文吃光光
在撰码以前建议你好好了解问题的本质, 你目前的实作不仅没办法
解决原问题还引入新的问题. 不过这边就直接讲怎么解决.
目标是新增物件的时候可以几乎不改程式码, 以你有想到用
std::vector 把物件蒐集起来这件事来看, 方向没有偏太多; 但这
个写法有几个缺点, 导致它并不是这个问题的解:
1. 定义了几个 A 物件是编译时期就知道的资讯, 所以延后到
执行时期做判断是浪费时间
2. STL 容器能用来储存同质性 (homogeneous) 的物件, 但它
并不能装异质性 (heterogeneous) 物件
考虑到扩充性可以用 std::tuple 来装所有物件, std::tuple 的好
处在于同质或异质物件都可以装在一起, 也可以个别做存取; 只是
没办法很简单地用循环对每个子物件做操作. 只要克服这个缺点你
所有问题都解了.
你可以在网络上搜寻 "for each element tuple" 找看看有没有相
关的程式码, 或者用下面现成的 (部份程式码在前一篇推文找得到
):
std::tuple<double, int> values{ 2.2, 1 };
apply(values, [] (auto&& value) {
std::cout << value << " ";
});
// print: 2.2 1
范例: https://wandbox.org/permlink/8qUcraz4XTH6VQ5E
你的目标从另一方面来看就是让编译器帮忙产生程式码, 这类的需
求通常和宏 (macro) 还有模板 (template) 脱不了关系, 所以至
少相关知识还要再加强.
上面的程式码为了节省篇幅用了 generic lambda, 如果 std::tuple
里装的是同质性物件, 你可以简单给个固定参数型别的函式物件就
好:
struct Foo {
void do_something() {}
};
struct User {
std::tuple<Foo, Foo> foos;
void do_something() {
apply(foos, [] (Foo& foo) { foo.do_something(); });
}
};
像这样你新增物件时唯一需要改的地方就只有资料成员的宣告了 (
或是成员初始化的程式码), 我针对你原来的程式码做了点修改, 让
它看起来比较像 C++ 一点:
范例: https://wandbox.org/permlink/ZSYdPco66Mt5SNuJ
如果只是想要具名的资料成员, 推文里就有提供搭配宏的解法了,
所以我还不懂你真正想要的东西是什么..
范例: https://wandbox.org/permlink/s4Uk4RpsbFj4hz4u
编译上或是其他的问题可以提出来让板友看看, 相信大家都会很热
意协助的. 但是如果遇到困难就绕路换个方式来做, 不仅没人知道
你想干什么, 最后也会很难写出合理的实作.