这个模板语法中的 "typename = T" 是什么意思?

3
有时我会看到这样的语法。
template<typename T,typename = int>
int foo(){
    //...
}

“typename = int”是什么意思?它在哪里可以使用?


4
就像函数可以有默认参数一样,模板参数也可以有默认类型。同样,就像函数参数不必命名一样,模板参数也不必命名。 - Some programmer dude
1
所以这个第二个类型名与具有名称“T”的第一个类型名相关联吗? - Kemsikov
1
不,T和未命名的“匿名”类型(默认为int)是无关的。 - Some programmer dude
但是如果第二个“匿名”类型没有命名,那么这种语法的原因是什么呢?如果它没有命名,我怎么使用它呢?你能给一个例子来说明为什么要使用这种语法吗?我可以理解在函数声明中有一个未命名的类型,但是然后你应该定义这个函数。我可以定义模板吗? - Kemsikov
2个回答

5

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>是两种不同的类型。

3

这很少使用...

但此处的默认值是typename,但您在此处不需要它,因为编译器本身可以自动重载函数并获得您传递的正确类型!

另外,这个typename适用于什么类型?这里没有意义!

它在使用嵌套模板时使用...

我在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>
}

这是链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接