什么是参数值的尖括号,它用于什么? [英] What is angle brackets for argument values, and what is it used for?

查看:1085
本文介绍了什么是参数值的尖括号,它用于什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用于指定类型的尖括号作为参数:

I am used to angle brackets being used to specify a type, as a parameter:

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

我不知道你可以传递

这里的代码是什么,为什么要传递一个在尖括号中?

What is the code here doing, and why is he passing a value in the angle brackets?

这是个好主意吗?何时?

Is this a good idea? When?

推荐答案

这里有两个不同的因素。

There are two different factors going on here.

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

First, it's possible to define templates that are parameterized over things other than just types. For example, here's a simple array type:

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

我们可以使用

Array<int, 137> myArray;

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

We know that vector<int> and vector<double> are different types. But now we must also point out that Array<int,137> and Array<int,136> are different types.

其次,当使用模板时,编译器必须能够找出所有模板参数的值。当你使用模板类时,这就是为什么你通常指定所有的模板参数。你不会说向量x ,而是说如 vector< double> x 。当使用模板函数时,大多数时候编译器可以找出参数。例如,要使用 std :: sort ,您只需说出

Second, when using templates, the compiler has to be able to figure out a value for all of the template arguments. When you're using template classes, this is why you typically specify all the template arguments. You don't say vector x, for example, but instead say something like vector<double> x. When using template functions, most of the time the compiler can figure out the arguments. For example, to use std::sort, you just say something like

std::sort(v.begin(), v.end());

但是,您也可以写

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

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

to be more explicit. But sometimes, you have a template function for which not all the arguments can be figured out. In your example, we have this:

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

注意 parseFlags 模板参数不能从函数的参数中推导出来。因此,要调用该函数,您必须指定模板参数,否则编译器无法计算出来。这就是为什么你会写

Notice that the parseFlags template parameter can't be deduced from just the arguments of the function. As a result, to call the function, you must specify the template parameter, since otherwise the compiler can't figure it out. That's why you'd write something like

Parse<0>(myString);

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

Here, the 0 is a template argument (resolved at compile-time), and myString is the actual argument (resolved at run-time).

实际上,可以有一些类型推断和一个显式类型参数。例如,在Boost中,有一个函数 lexical_cast 可以对字符串类型进行转换。从非字符串类型转换为字符串类型的函数签名是

You can actually have methods that combine a bit of type inference and a bit of explicit type parameters. For example, in Boost, there's a function lexical_cast that can do conversions to and from string types. The function signature to convert from a non-string type to a string type is

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

在这里,如果调用 lexical_cast 编译器可以弄清楚 Source 是什么,但它不能推导出 Target 而没有一些提示。因此,要使用 lexical_cast ,您将会写下

Here, if you call lexical_cast, the compiler can figure out what Source is, but it can't deduce Target without some hints. To use lexical_cast, therefore, you'd write something like

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

更一般地说,编译器说你必须指定一些数目的模板参数并将尝试推导出其余的。如果可以,伟大的!如果没有,它是一个编译时错误。使用这个,你可以编写一个函数

More generally, the compiler says that you have to specify some number of template arguments (optionally 0), and it will try to deduce the rest. If it can, great! If not, it's a compile-time error. Using this, if you'd like, you could write a function like

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

$ b b

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

To call this function, you'd have to invoke it like this:

DoSomething<intArg>(otherArg);

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

Here, this works because you have to explicitly tell the compiler what IntArgument is, but then the compiler can deduce TypeArgument from the type of the argument to DoSomething.

希望这有助于!

这篇关于什么是参数值的尖括号,它用于什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆