2013-09-09 2 views
39

Пожалуйста, объясните мне, почему следующий фрагмент кода подходит и работает отлично. Я очень смущен.Параметр по умолчанию шаблон частичной специализации

#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?

+10

+1 для обучения меня, что аргументы по умолчанию продолжают применяться к специализациям. – chris

+0

+1 для почти такой же причины @chris сказал. не видел этого. – WhozCraig

+0

Согласен. Отличный вопрос и (в частности), превосходная работа по его заданию, полная SSCCE и хорошее описание как фактического, так и ожидаемого поведения. Отлично сработано! –

ответ

0

Когда вы пишете Base<> base;, компилятор попытается выяснить, возможно ли создание класса Base<> или нет, если возможно, что код будет работать нормально. В этом случае это возможно из-за аргумента шаблона по умолчанию Base, потому что компилятор знает, если вы, если вы напишете Base<>, ему нужно создать объект Base<int,double>. то есть из-за:

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

Таким образом, код работает нормально.

+0

Вопрос в том, почему он не должен fali? @Saksham – deeiip

+0

он отвечает на вопрос ?? – Saksham

+0

Как указано в аргументе по умолчанию, код будет работать. Я думаю, что это ответ – deeiip

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

Здесь значения/инициализация по умолчанию для A и B объявлены соответственно как int и double.

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

Здесь в определениях класса, первый аргумент это то, как постоянное значение (здесь ИНТ, почему? Объявляет так просто сделать вещи комплекса лучше удалить первый аргумент шаблона), а второй аргумент шаблона является B, кто по умолчанию Значение «double».

Base<> base; 

При создании объекта класса. Хотя вы не указываете аргументы шаблона, компилятор принимает значения по умолчанию для аргументов (A и B), которые являются «int» и «double», и код выполняется без каких-либо ошибок или предупреждений.
Посмотрите, что происходит, когда вы создаете объект как:
Base<float,char> b; или Base<char,char> b;

+0

Я верю в вопрос: почему в этом случае выбирается частичная специализация, а не первичный шаблон. Я не вижу в этом ответа. – Mat

19

по умолчанию Аргумент относится к специализации - и, по сути, специализация должна принять (так сказать) по умолчанию аргумент базового шаблона (ы). Попытка указать значение по умолчанию по специализации:

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

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

... является ошибкой.

Аналогично, если мы изменим специализацию, так что его специализация для типа другого, чем по умолчанию, предоставленное базовый шаблон:

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

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

... то база шаблона будет выбрана.

Итак, что происходит: сначала выбираются типы аргументов шаблона. В этом случае (тип не указан при создании экземпляра) оба типа основаны на аргументах шаблона по умолчанию, указанных в базовом шаблоне.

Затем (как в основном отдельный шаг) он выполняет аналог разрешения перегрузки на всех шаблонах, соответствующих этим типам аргументов. Как обычно для разрешения перегрузки, тип, указанный явно явно, более предпочтительный, чем тот, который указан неявно, поэтому ваша специализация (которая явно указана int) предпочтительнее базового шаблона (который неявно задает int).