Конструктор по умолчанию, определенный с аргументами по умолчанию вне определения класса, почему это работает? и что происходит с задействованными шаблонами?

Я знаю, что это дурной тон и что значения по умолчанию должны быть указаны в объявлении, но если вы позволите мне на минутку... почему это компилируется? а что именно происходит?

#include <iostream>
using namespace std;

class test
{
public:
    test(int n);
};

test::test(int n = 666)
{
    cout << n;
}

int main()
{
    test t;

    cin.sync();
    cin.ignore();

    return 0;
}

Вывод: 666

.. как шаблоны влияют на один и тот же фрагмент кода?

template <class T>
class test
{
public:
    test(int n);
};

template <class T>
test<T>::test(int n = 666)
{
    cout << n;
}

int main()
{
    test<int> t;

    cin.sync();
    cin.ignore();

    return 0;
}

Ошибка: нет подходящего конструктора по умолчанию

Спасибо за уделенное время!


person whysoconfused    schedule 24.07.2011    source источник
comment
Дополнительные сведения о параметрах по умолчанию: ideone.com/mbTJU.   -  person Dennis Zickefoose    schedule 24.07.2011


Ответы (2)


Похоже, что спецификация C++ специально разрешает первый случай и запрещает второй!

Цитата из спецификации С++ (8.3.6/4):

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

Похоже, что для нешаблонных функций вы действительно можете ввести аргументы по умолчанию позже. Не знаю, почему это не работает для шаблонов!

person templatetypedef    schedule 24.07.2011
comment
Спасибо за цитату из спецификации C++! - person whysoconfused; 24.07.2011

Первый случай разрешен стандартом; Я помню, что @Johannes задал этот вопрос, а @Nawaz ответил. (Редактировать: вот соответствующий вопрос).

Причина запрета версии template заключается в том, что функции template вызываются только при явном создании экземпляра. В вашем случае компилятор смотрит на объявление как

test<int> t;

-->Изменить: может отличаться от компилятора к компилятору. В gcc работает нормально.‹--

Почему это может не работать в некоторых компиляторах может быть Поскольку вы явно не создаете экземпляр как t(N), компилятор не сможет разрешить test<T>::test(int n = 666). Таким образом, он ищет конструктор по умолчанию без аргументов, который не найден; таким образом приводит к ошибке.

person iammilind    schedule 24.07.2011
comment
Хотя я не принял ваш ответ, я нашел его информативным, спасибо за это. - person whysoconfused; 25.07.2011