有时我会看到这样的语法。
template<typename T,typename = int>
int foo(){
//...
}
typename = int
部分是什么意思?
可以用在哪里?
答案 0 :(得分:4)
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>
是两种不同的类型。
答案 1 :(得分:3)
很少使用...
但这是 typename 的默认值,但您在这里不需要它,因为编译器本身可以自动重载函数并为您传递的正确参数获取正确的类型!
它也输入什么 typename ?这里没有意义!
它在您使用嵌套模板时使用...
我在 C++ 的原始参考资料中发现:
<块引用>模板模板参数的模板参数列表可以有 他们自己的默认参数,只有在 模板模板参数本身在范围内:
// 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>
}