可变参数模板功能的专业化

时间:2014-07-17 23:48:35

标签: c++ templates c++11 variadic-templates

我试图为我定义的某个特定类型的层次结构聚合成员变量的值。

使用可变参数模板化函数很容易做到这一点。

当我尝试将作为字符串调用此模板的函数的名称作为第一个参数传递时,我没有太多运气。 这很难解释,所以下面是一些代码,我必须证明我要做的事情。

尝试编译此结果: 错误C2993:' std :: string' :非类型模板参数的非法类型' str'

我试图做的不可能吗?或者我只是以错误的方式解决这个问题?

std::ostringstream output;
int objCounter = 0;

void set_results() {
    output << "\n" << std::endl;
}

template <typename obj,  typename ...objs>
void set_results(obj objHead, objs... objTail) {
    ++objCounter;
    output << "Argument (" << objCounter << ") \t" << objHead.bytes << std::endl;
    set_results(objTail...);
}

template <std::string str, typename ...objs>
void set_results(std::string objHead, objs... objTail) {
    output << "Leaf Function: " << objHead << std::endl;
    set_results(objTail...);
}

class objDep {
public:
    int bytes;
    objDep(int b) : bytes(b) {}
};


int _tmain(int argc, _TCHAR* argv[])
{
    objDep one(1);
    objDep two(2);
    objDep three(3);
    objDep four(4);

    set_results(std::string("main"), one, two, three, four);

    std::cout << output.str() << std::endl;

    return 0;
}

2 个答案:

答案 0 :(得分:5)

更改

template <std::string str, typename ...objs>
void set_results(std::string objHead, objs... objTail) {
    output << "Leaf Function: " << objHead << std::endl;
    set_results(objTail...);
}

为:

template <typename ...objs>
void set_results(std::string objHead, objs... objTail) {
    output << "Leaf Function: " << objHead << std::endl;
    set_results(objTail...);
}

您不能拥有std::string类型的模板参数,无论如何,完全不清楚您希望str代表什么。

请注意,功能模板不能部分专业化。通过此替换,您将有set_results的两个重载。将选择具有std::string参数的那个,因为它更专业。

答案 1 :(得分:4)

模板参数列表中根本不需要std::string str

template <typename ...objs>
void set_results(std::string objHead, objs... objTail)

首先,它是未使用的,非类型模板参数只能是整数(intlong等),枚举或函数符号。

模板指定函数或类是通用的方式。话说:

template <typename obj, typename ...objs>
void set_results(obj objHead, objs... objTail)

表示“给定某种类型,称之为obj”,以及一些类型列表,称之为objsset_results采用类型obj的值和一系列分别为objs类型的值,并返回void“。