这个模板语法 "typename = T" 是什么意思?
What this template syntax "typename = T" mean?
有时我会看到这样的语法。
template<typename T,typename = int>
int foo(){
//...
}
什么部分typename = int
是什么意思?
可以用在什么地方?
foo
有两个模板参数。第一个称为 T
,第二个未命名,默认为 int
.
仅在您的代码段中,没有理由使用第二个参数。 SFINAE 经常会出现未命名的模板参数。来自 cppreference 的示例:
// primary template handles non-referenceable types:
template<class T, class = void>
struct reference_traits {
using add_lref = T;
using add_rref = T;
};
// specialization recognizes referenceable types:
template<class T>
struct reference_traits<T, std::void_t<T&>> {
using add_lref = T&;
using add_rref = T&&;
};
template<class T>
using add_lvalue_reference_t = typename reference_traits<T>::add_lref;
template<class T>
using add_rvalue_reference_t = typename reference_traits<T>::add_rref;
主模板具有第二个参数的唯一原因是它可以专门化。在可能的情况下,实例化更专业的专业化。如果此操作失败(因为 T&
无效),则“替换失败不是错误”(SFINAE) 开始并实例化主模板。
未命名参数的一个更简单的例子是当你想要一个模板参数只是作为一个标签来区分不同的实例化:
template<typename = int>
struct bar {
// ...
};
即使 bar
的实现不依赖于模板参数,您可能希望 bar<double>
和 bar<std::string>
是两种不同的类型。
这个很少用到...
但这是类型名的默认值,但您在这里不需要它,因为编译器本身可以自动重载函数并为您传递的正确参数获取正确的类型!
它还键入什么类型名称?这里没有意义!
它在您使用嵌套模板时使用...
我在 C++ 的原始参考资料中发现:
The template parameter lists of template template parameters can have
their own default arguments, which are only in effect where the
template template parameter itself is in scope:
// class template, with a type template parameter with a default
template<typename T = float> struct B {};
// template template parameter T has a parameter list, which
// consists of one type template parameter with a default
template<template<typename = float> typename T> struct A
{
void f();
void g();
};
// out-of-body member function template definitions
template<template<typename TT> class T>
void A<T>::f()
{
T<> t; // error: TT has no default in scope
}
template<template<typename TT = char> class T>
void A<T>::g()
{
T<> t; // ok: t is T<char>
}
有时我会看到这样的语法。
template<typename T,typename = int>
int foo(){
//...
}
什么部分typename = int
是什么意思?
可以用在什么地方?
foo
有两个模板参数。第一个称为 T
,第二个未命名,默认为 int
.
仅在您的代码段中,没有理由使用第二个参数。 SFINAE 经常会出现未命名的模板参数。来自 cppreference 的示例:
// primary template handles non-referenceable types:
template<class T, class = void>
struct reference_traits {
using add_lref = T;
using add_rref = T;
};
// specialization recognizes referenceable types:
template<class T>
struct reference_traits<T, std::void_t<T&>> {
using add_lref = T&;
using add_rref = T&&;
};
template<class T>
using add_lvalue_reference_t = typename reference_traits<T>::add_lref;
template<class T>
using add_rvalue_reference_t = typename reference_traits<T>::add_rref;
主模板具有第二个参数的唯一原因是它可以专门化。在可能的情况下,实例化更专业的专业化。如果此操作失败(因为 T&
无效),则“替换失败不是错误”(SFINAE) 开始并实例化主模板。
未命名参数的一个更简单的例子是当你想要一个模板参数只是作为一个标签来区分不同的实例化:
template<typename = int>
struct bar {
// ...
};
即使 bar
的实现不依赖于模板参数,您可能希望 bar<double>
和 bar<std::string>
是两种不同的类型。
这个很少用到...
但这是类型名的默认值,但您在这里不需要它,因为编译器本身可以自动重载函数并为您传递的正确参数获取正确的类型!
它还键入什么类型名称?这里没有意义!
它在您使用嵌套模板时使用...
我在 C++ 的原始参考资料中发现:
The template parameter lists of template template parameters can have their own default arguments, which are only in effect where the template template parameter itself is in scope:
// class template, with a type template parameter with a default template<typename T = float> struct B {}; // template template parameter T has a parameter list, which // consists of one type template parameter with a default template<template<typename = float> typename T> struct A { void f(); void g(); }; // out-of-body member function template definitions template<template<typename TT> class T> void A<T>::f() { T<> t; // error: TT has no default in scope } template<template<typename TT = char> class T> void A<T>::g() { T<> t; // ok: t is T<char> }