对象成员和标准类型的模板函数

时间:2014-06-05 15:14:05

标签: c++ templates member

我基本上想将下面的两个打印函数合并到一个函数中,如果实际上可行的话。也就是说,我希望有一个模板函数只接受普通类型(int,float,std :: string等)和另一个指定成员的参数。

#include <iostream>
#include <string>

struct MyStruct{
  int a;
  int b;
  std::string c;

  MyStruct(int a_, int b_, std::string c_) : a(a_), b(b_), c(c_) {}
};

template <typename TObject, typename TMember>
void print(const TObject &object, TMember member){
  std::cout << object.*member << std::endl;
}

template <typename T>
void print(const T &val){
  std::cout << val << std::endl;
}

int main(int argc, char *argv[]){
  MyStruct s(50, 100, "this is a test\n");
  print(s, &MyStruct::a);
  print(s, &MyStruct::b);
  print(s, &MyStruct::c);

  print(s.a);
  print(s.b);
  print(s.c);
}

也许有某种模板魔法可以解决这个问题。感谢。

1 个答案:

答案 0 :(得分:1)

我不能让它适用于原始类型,因为不允许指向原始类型成员的指针(这里是GCC错误):

  

错误:创建指向非类型'int'

成员的指针

然而,经过大量的摸索,由于编译器认为我试图让成员指针指向一个构造函数(好像),我终于让它适用于类类型(所有其余的):

首先,我们需要一些我知道第一个元素的结构,只是为了获得一个指向结构开头的有效成员指针:

struct a{char a;};

接下来,我们为模板参数添加一个默认值:一个将TObject映射到TObject的成员指针:

template <typename TObject, typename TMember = TObject TObject::*>

因为我们使用数据成员指针,所以强制转换是可以的:

void print(const TObject &object, TMember member = (TMember)&a::a){
  std::cout << object.*member << std::endl;
}

Voila,我们的打印功能不仅可以使用成员指针,如果我们想要打印对象本身,我们甚至可以省略它们。
不知怎的,我不能让自己称之为简化......但