在实际中碰到这样一类问题,有一个结构体,中间包括各种不同的类型,但有一种函数,需要对不同类型字段的值都进行统计、排序等操作,函数中90%的代码都相同,唯一的不同是获取目标结构体的不同字段的值,为了避免针对不同类型的字段,声明不同类型的变量,通过封装get_field_val(struct)为模板函数解决此问题。如下代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct info_t{
 int a;
 string b;
 int c;
};

class account{
public:
 template<class T>
 void account_field(int type)
 {
 vector<T> vec;
 for(int i = 0; i < 8; i++)
 {
 T val;
 val = get_val<T>(infos[i], type);
 vec.push_back(val);
 }
 //统计, 排序xxxx一堆工作
 //...
 return;
 }

 template<class T>
 T get_val(info_t info, int type)
 {
 if(type == 1)
 return info.a;
 else
 return info.c;
 }

private:
 info_t infos[8];
};

template<> string account::get_val<string>(info_t info, int type)
{
 return info.b;
}

int main(void)
{
    account a;
    a.account_field<int>(1);
    a.account_field<string>(2);
    return 0;
}

如上,使用模板get_val函数和type获取指定字段的值,并且针对string进行模板的特化。对于类成员模板函数的特化,必须放在类定义的外部,否则会报Explicit specialization in non-namespace scope的错误,具体的原因可以参见如下说明。如果没有该特化,也可以直接重载一个函数,但这样就不能在调用函数时显示特化了,特别是对于调用a.account_field<T>(type)的函数。

An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member.

An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member.

,