使用仅存在于某些数据类型中的字段的C ++模板函数?

时间:2009-07-17 11:14:19

标签: c++ templates

是否有可能有一个C ++模板函数可以访问其输入数据中的不同字段,具体取决于传入输入数据的类型

e.g。我有以下形式的代码:

typedef struct
{
  int a;
  int b;
}s1;

typedef struct
{
  int a;
}s2;

template <class VTI_type> void myfunc(VTI_type VRI_data, bool contains_b)
{
  printf("%d", VRI_data.a);

  if(contains_b) // or suggest your own test here
    printf("%d", VRI_data.b); // this line won't compile if VTI_type is s2, even though s2.b is never accessed
}

void main()
{
  s1 data1;
  data1.a = 1;
  data1.b = 2;
  myfunc <s1> (data1, true);

  s2 data2;
  data2.a = 1;
  myfunc <s2> (data2, false);
}

所以我们想要使用来自许多不同数据类型的字段A,并且工作正常。

但是,某些数据还有一个需要使用的字段B - 但是如果模板知道它正在查看不包含字段B的数据类型,则需要删除访问字段B的代码。 p>

(在我的示例中,结构是外部API的一部分,因此无法更改)

4 个答案:

答案 0 :(得分:5)

详细说明建议使用模板专业化:

template <class T> void myfunc(T data)
{  
    printf("%d", VRI_data.a);  
}

// specialization for MyClassWithB:
template <>
void myfunc<MyClassWithB>(MyClassWithB data)
{
    printf("%d", data.a);  
    printf("%d", data.b); 
}

但是,这需要每班专业化,没有b的“自动检测”。此外,你重复了很多代码。

您可以将“拥有b”方面分解为帮助模板。一个简单的演示:

// helper template - "normal" classes don't have a b
template  <typename T>
int * GetB(T data) { return NULL; }  

// specialization - MyClassWithB does have a b:
template<>
int * GetB<MyClassWithB>(MyClassWithB data) { return &data.b; }

// generic print template
template <class T> void myfunc(T data)
{  
    printf("%d", VRI_data.a);  
    int * pb = GetB(data);
    if (pb)
      printf("%d", *pb); 
}

答案 1 :(得分:3)

解决方案1:您可以使用模板专业化。专业化可以在每个班级或一些更一般的特征上进行。

答案 2 :(得分:0)

如果您不想硬编码S1&amp;然后你可以在代码中进行S2专业化:

typedef struct
{
  int a;
  int b;
}s1;

typedef struct
{
  int a;
}s2;

template <class T, bool contains_b> 
struct MyFunc
{

    void operator()(T data)
    {
        printf("%d", data.a);
    }

};


template <class T> 
struct MyFunc<T, true>
{
    void operator()(T data)
    {
        printf("%d", data.a);
        printf("%d", data.b); 

    }
};

template<class T, bool contains_b>
void myFunc(T t)
{
    MyFunc<T, contains_b> m;
    m(t);
}

int _tmain(int argc, _TCHAR* argv[])
{
 s1 data1;
  data1.a = 1;
  data1.b = 2;

  myFunc<s1,true>(data1) ;

  s2 data2;
  data2.a = 1;
  myFunc<s2,false>(data2);
  return 0;
}

答案 3 :(得分:0)

要详细说明其他人的答案,似乎最好的方法是在不跨多个模板重复相同代码的情况下执行此操作,只需要一个“额外的东西”功能(大多数数据类型为空,但包含任何代码)具有附加数据的对象),其中“模板专门化”选择为每种数据类型运行哪个“额外的东西”函数。

更新的代码:

typedef struct
{
  int a;
  int b;
}s1;

typedef struct
{
  int a;
}s2;

template <class VTI_type> void extraStuff(VTI_type VRI_data)
{
}

template <> void extraStuff<s1>(s1 VRI_data)
{
  printf(" and b = %d\n", VRI_data.b);
}

template <class VTI_type> void myfunc(VTI_type VRI_data)
{
  printf("a = %d\n", VRI_data.a);
  extraStuff(VRI_data);
}

void main()
{
  s1 data1;
  data1.a = 1;
  data1.b = 2;
  myfunc <s1> (data1);

  s2 data2;
  data2.a = 1;
  myfunc <s2> (data2);
}