60

请向我解释为什么以下代码符合并完美运行。我很困扰。

#include<iostream>
template<class A = int, class B=double>
class Base
{};

template<class B>
class Base <int, B>
{
public:
  Base()
  {
     std::cout<<"it works!!!!!\n";
  }
};

int main()
{
  Base<> base; // it prints "it works!!!!!"
  return 0;
}

不应该落入模板类Base的泛化形式吗?

4

3 回答 3

37

The default argument applies to the specialization -- and, in fact, a specialization must accept (so to speak) the base template's default argument(s). Attempting to specify a default in the specialization:

template<class A = int, class B=double>
class Base
{};

template<class B=char>
// ...

...is an error.

Likewise, if we change the specialization so that its specialization is for a type other than the default provided by the base template:

template<class A = int, class B=double>
class Base
{};

template<class B>
class Base <char, B>

...then the base template will be chosen.

So, what's happening is this: first the types for the template arguments are chosen. In this case (no type specified at instantiation), both types are based on the default template arguments specified in the base template.

Then (as a basically separate step) it carries out an analog of overload resolution on all templates that fit those argument types. As usual for overload resolution, a type that's specified explicitly is preferred over one that's specified implicitly, so your specialization (which specified int explicitly) is preferred over the base template (which specified int implicitly).

于 2013-09-09T15:07:15.343 回答
0

当您编写时Base<> base;,编译器将尝试找出Base<>类的实例化是否可能,如果有可能代码可以正常工作。在这种情况下,可能由于 Base 的默认模板参数,因为编译器知道您是否编写Base<>它需要创建Base<int,double>. 即:因为:

template<class A = int, class B=double>
class Base
{};

所以代码工作正常。

于 2013-09-09T14:37:01.863 回答
0
template<class A = int, class B=double>
class Base
{};

这里 A 和 B 的默认值/初始化已分别声明为 int 和 double。

 template<class B>
 class Base <int, B>

在类定义中,第一个参数类似于常量值(这里是 int;为什么这样声明只会让事情变得复杂?最好删除第一个模板参数),第二个模板参数是 B,默认值为“double”。

Base<> base;

当你创建类的对象时。尽管您没有指定模板参数,但编译器采用参数(A 和 B)的默认值,即“int”和“double”,并且代码执行时不会出现任何错误或警告。
看看当你创建对象时会发生什么:
Base<float,char> b;Base<char,char> b;

于 2013-09-09T14:59:48.220 回答