This question already has answers here:
Reason for using non-type template parameter instead of regular parameter?
(6个答案)
2年前关闭。
我习惯将尖括号用于指定类型,作为参数:
但是在rapidjson中,有这样的代码:
我不知道您可以在尖括号内传递值-认为尖括号仅用于类型名称。
这里的代码在做什么,为什么他在尖括号中传递一个值?
这是一个好主意吗?什么时候?
我们可以这样使用
我们知道
其次,使用模板时,编译器必须能够为所有模板参数找出一个值。使用模板类时,这就是为什么通常指定所有模板参数的原因。例如,您不说
但是,您也可以写
更明确地说。但是有时候,您有一个模板函数,对于该函数,并非所有参数都可以被找出来。在您的示例中,我们有:
注意,不能仅从函数的参数推导
此处,0是模板参数(在编译时解析),而
实际上,您可以使用结合了一些类型推断和一些显式类型参数的方法。例如,在Boost中,有一个函数
在这里,如果您调用
更一般而言,编译器说您必须指定一定数量的模板参数(可选为0),它将尝试推断其余的参数。如果可以的话,太好了!如果不是,则为编译时错误。如果需要,可以使用此代码编写类似的函数
要调用此函数,您必须像这样调用它:
在这里,这是可行的,因为您必须显式告诉编译器
希望这可以帮助!
(6个答案)
2年前关闭。
我习惯将尖括号用于指定类型,作为参数:
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
模板参数。因此,要调用该函数,必须指定template参数,否则编译器将无法确定该参数。这就是为什么你会写类似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/