参数值的尖括号是什么,它用于什么?

时间:2012-02-08 22:02:16

标签: c++ templates syntax

我习惯使用尖括号来指定一个类型,作为参数:

vector<int> vecOfInts ;

但在rapidjson中,有这样的代码:

document.Parse<0>(json) ;

document.Parse方法的签名是:

template <unsigned parseFlags>
GenericDocument& Parse(const Ch* str) {
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
    GenericStringStream<Encoding> s(str);
    return ParseStream<parseFlags>(s);
}

我不知道你可以在尖括号内传递 - 思想尖括号仅用于类型名称。

这里的代码是什么,为什么他在尖括号中传递

这是个好主意吗?当α

1 个答案:

答案 0 :(得分:19)

这里有两个不同的因素。

首先,可以定义参数化的模板,而不仅仅是类型。例如,这是一个简单的数组类型:

template <typename T, size_t N> struct Array {
    T arr[N];
};

我们可以像

一样使用它
Array<int, 137> myArray;

我们知道vector<int>vector<double>是不同的类型。但现在我们还必须指出Array<int,137>Array<int,136>是不同的类型。

其次,使用模板时,编译器必须能够找出所有模板参数的值。当您使用模板类时,这就是您通常指定所有模板参数的原因。例如,您没有说vector x,而是说vector<double> x之类的内容。使用模板函数时,编译器大多数时候都可以找出参数。例如,要使用std::sort,您只需说出

之类的内容
std::sort(v.begin(), v.end());

但是,您也可以写

std::sort<vector<int>::iterator>(v.begin(), v.end());

更明确。但有时候,你有一个模板函数,并不是所有的参数都可以计算出来。在您的示例中,我们有:

template <unsigned parseFlags>
GenericDocument& Parse(const Ch* str) {
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
    GenericStringStream<Encoding> s(str);
    return ParseStream<parseFlags>(s);
}

请注意,parseFlags模板参数不能仅从函数的参数中推断出来。因此,要调用该函数,必须指定模板参数,否则编译器无法识别它。这就是你写“

”之类的原因
Parse<0>(myString);

这里,0是模板参数(在编译时解析),myString是实际参数(在运行时解析)。

实际上,您可以拥有将一些类型推断和一些显式类型参数组合在一起的方法。例如,在Boost中,有一个函数lexical_cast可以与字符串类型进行转换。要从非字符串类型转换为字符串类型的函数签名是

template <typename Target, typename Source>
    Target lexical_cast(const Source& arg);

在这里,如果你调用lexical_cast,编译器可以找出Source是什么,但如果没有一些提示,它就无法推断Target。因此,要使用lexical_cast,您需要编写类似

的内容
std::string myString = boost::lexical_cast<std::string>(toConvertToString);

更一般地说,编译器说你必须指定一些模板参数(可选0),它会尝试推断其余的。如果可以,太棒了!如果不是,那就是编译时错误。使用它,如果你愿意,你可以写一个像

这样的函数
template <int IntArgument, typename TypeArgment>
    void DoSomething(const TypeArgument& t) {
       /* ... */
}

要调用此函数,您必须像这样调用它:

DoSomething<intArg>(otherArg);

这里有效,因为你必须明确地告诉编译器IntArgument是什么,但编译器可以从TypeArgument的参数类型中推导出DoSomething

希望这有帮助!