[英]C++ template class = typename
什么template <class = typename T::type>
是什么意思? 你能引用我的博客,说明这个吗?
template <typename A>
struct B { typedef typename A::type type; };
template <
class T,
class = typename T::type, // SFINAE failure if T has no member type
class U = typename B<T>::type // hard error if T has no member type
// (guaranteed to not occur as of C++14)
> void foo (int);
首先,我将解释typename T::type
。 这只是成员类型的访问。 以下是访问成员类型的示例:
struct foo {
using bar = int;
};
int main() {
foo::bar var{};
// var has type int
}
那么为什么这个typename
呢? 它只是意味着我们想要访问一个类型。 由于我们在模板中而T
是未知类型,因此foo::bar
也可能意味着访问静态变量。 为了消除歧义,我们表示我们有效地希望通过显式键入typename
来访问类型。
好的,现在这个class =
意味着什么?
class =
表示与typename =
相同的东西。 在声明模板类型参数时,我们使用class
或typename
引入:
template<typename A, typename B>
struct baz {};
但是作为C ++中的任何参数,名称是可选的。 我本来可以写这个,以下是完全等价的:
template<typename, typename>
struct baz {};
另外,您知道在函数参数中,我们可以指定默认值吗? 像那样:
void func(int a, int b = 42);
int main () {
func(10); // parameter b value is 42
// We are using default value
}
我们也可以省略参数名称:
void func(int, int = 42);
就像函数参数一样,模板参数可以省略它的名称,并且可以有一个默认值。
template<typename, typename = float>
struct baz {};
baz<int> b; // second parameter is float
现在我们有这个声明:
template <
class T,
class = typename T::type, // SFINAE failure if T has no member type
class U = typename B<T>::type // hard error if T has no member type
// (guaranteed to not occur as of C++14)
> void foo (int);
这里我们声明一个以int作为参数的函数,并且有三个模板参数。
第一个参数是一个简单的命名参数。 名称是T
,它是一个类型模板参数。 第二个也是类型参数,但它没有名称。 但是,它的默认值为T::type
,它是T
的成员类型。 我们通过指定typename
明确告诉编译器T::type
必须是T
的成员类型。 第三个参数类似于第二个参数。
这就是SFINAE的用武之地:当使用默认参数,但T::type
作为成员类型不存在时,如何将第二个模板参数分配给它? 我们做不到。 如果T::type
不存在,我们就不能分配第二个模板参数。 但是编译器不会使它成为错误,而是简单地尝试另一个函数,因为有可能另一个函数可以调用。
这与简单重载非常相似。 你有f
功能。 它需要一个float
参数,另一个带有std::string
重载。 想象一下你叫f(9.4f)
。 编译器是否因为一个float
不能构造std::string
而窒息? 没有! 编译器不是傻瓜。 它将尝试另一个重载,并将找到float
版本并调用它。 在SFINAE中,可以进行类似的类比。 编译器不会停止,因为某些重载需要模板参数中的未定义类型。 它会尝试另一个重载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.