template <class = typename T::type>是什么意思?你能给我介绍一下描述这一点的博客吗?
这个问题来源于对cpp参考文献中的sfinae的解释
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);发布于 2018-03-21 14:32:00
首先,我将解释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的成员类型。我们明确地告诉编译器,T::type必须是T的成员类型,方法是指定typename。第三个参数类似于第二个参数。
这就是SFINAE的开场白:当使用默认参数,但T::type作为成员类型不存在时,如何将第二个模板参数分配给它呢?如果T::type不存在,我们就不能分配第二个模板参数。但是编译器不会使它成为一个错误,而是简单地尝试另一个函数,因为有可能会调用另一个函数。
这与简单的重载非常相似。您有f函数。它需要一个float参数,另一个需要std::string的重载。想象一下你打电话给f(9.4f)。编译器会因为std::string不能从float构建而窒息吗?不是的!编译器才不傻。它将尝试另一个重载,并将找到float版本并调用它。在SFINAE中,也可以作类似的类比。编译器不会停止,因为某个地方的重载需要模板参数中未定义的类型。它会尝试另一个过载。
https://stackoverflow.com/questions/49408294
复制相似问题