+ -
当前位置:首页 → 问答吧 → 模板能解决吗?宏能解决吗?你能解决吗?

模板能解决吗?宏能解决吗?你能解决吗?

时间:2010-08-09

来源:互联网

本帖最后由 pesoft 于 2010-08-09 16:02 编辑

问题描述:
  1. class CData
  2. {
  3. public:
  4. int m_nVal;
  5. float m_fVal;
  6. bool m_bVal; // 失误。。。。这里我改了!
  7. };
复制代码
用什么方法处理一下能使用类似下面的代码来输出这个结构中的每个值:
  1. for(int idx=0; idx < 3; ++idx)
  2. {
  3. std::cout << vec[idx] <<std::endl;
  4. }
复制代码
各种offsetof,模板,宏,上吧!挑战一下你的智慧!

作者: pesoft   发布时间: 2010-08-09

LZ 05年注册的就发过此主题,

作者: ecjtubaowp   发布时间: 2010-08-09

float m_fVal;
        bool m_fVal;

你能编译过?

作者: 星空天神   发布时间: 2010-08-09



QUOTE:
LZ 05年注册的就发过此主题,
ecjtubaowp 发表于 2010-08-09 15:40




    神人!

作者: rain_fish   发布时间: 2010-08-09

两个m_fVal………………

作者: daybreakcx   发布时间: 2010-08-09

难道已经有解决主要问题的方法了?

作者: pesoft   发布时间: 2010-08-09

这样的功能在java, C#, lua, python中都很容易。

1. 它们在运行时保存丰富类型信息

2. 它们都有可以表达任意对象的变量

java, C#是object(配合boxing)
lua, python本来就是动态类型


C++显然都不具备。

因为不具备2, 所以d[ i ] 必须有一个确定的返回类型。

要么可以使用次之一点的语法来避免返回:
  1. for (int i=0; i<n; ++i) cout<<d[i]; // 改为:
  2. for (int i=0; i<n; ++i) d.save(i, cout);
复制代码
  1. T::save(int i, std::ostream& os)
  2. {
  3.       switch(i)
  4.       {
  5.       case 0: os<<i; break;
  6.       case 1: os<<f; break;
  7.       case 2: os<<b; break;
  8.       }
  9. }
复制代码
要么就构造出一个多态类型作为返回类型:
  1. struct R
  2. {
  3.       void const* x;
  4.       void (*out)(std::ostream& os, void const * x);
  5. };

  6. std::ostream& operator(std::ostream& os, R const& r)
  7. {
  8.       r.out(os, r.x);
  9.       return os;
  10. }

  11. template<typename T> void out(std::ostream& os, void const* x)
  12. {
  13.       os<<*static_cast<T const*>(x);
  14. }

  15. R X::operator[](ptrdiff_t i)
  16. {
  17.       R r;
  18.       switch (i)
  19.       {
  20.       case 0: r.v = &this->i; r.out = out<int>; break;
  21.       case 1: r.v = &this->f; r.out = out<float>; break;
  22.       ...
  23.       }
  24.       return r;
  25. }
复制代码
如果还需要更丰富的类型信息, 要么使用其他语言。
否则就要很繁琐的手工添加这些信息。
可以参考一些串行化库是添加这些信息并工作的。

比如有Qt那样的, 不直接声明成员, 而是用宏来声明, 顺便插入一些代码。
也有非侵入式的, 直接解析C源代码, 不编译, 仅生成类型信息。
好像CU有人就是这样做的。

作者: OwnWaterloo   发布时间: 2010-08-09

OwnWaterloo 兄的办法的确可以满足这种少量的需求。
上面其实是我对目前遇到问题的一个简化版本。
我详细地描述一下问题,真实的问题。
1.我有很多类,但每个类中的一部分不同类型的数据要实现存储。
2.由于我比较懒,我想把这些数据放到一个数组中,然后在一个循环中存入文件。
但是,用模板可以识别类成员的类型,并将它们的地址存放到一个代理类中。起初发我期望把这个代理类指针存入一个数组,然后针对每一个将要存盘的类实例,使用这个数组中的地址存取。
可惜,我发现,在循环的过程中,我无论如何也法得到数据类型!

作者: pesoft   发布时间: 2010-08-09