c++ - 什么是参数值的尖括号,它的用途是什么?

标签 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);
}

我不知道您可以在尖括号内传递 - 以为尖括号仅用于类型名。

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

这是个好主意吗?什么时候?

最佳答案

这里有两个不同的因素。

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

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 .

希望这会有所帮助!

关于c++ - 什么是参数值的尖括号,它的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9202200/

相关文章:

syntax - 带下划线的十六进制值语法的含义是什么?例如:parameter FOO = 20'h0002_0

c++ - 如何防止为未实现方法的对象生成模板

c# - 协议(protocol)与接口(interface)

c++ - 头肩检测(从顶部看)

c++ - 我很困惑为什么我的 fillDeck 函数说, "assigning to ' char *' from incompatible type ' const char *”

c++ - (C++) 循环 : User Input Without Reserving Memory

C++ 继承,发送指向基类的指针

java - JSF 2 : How build components correctly?

c++ - 显式成员特化

c++ - 如何在头文件中声明要在两个.cpp 中使用的变量?