I am aware this is bad form and that default-values should be specified in the declaration, but if you would please indulge me for a moment.. why does this compile? and what is happening exactly?
#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;
}
Output: 666
.. how do templates affect the same piece of code?
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;
}
Error: no appropriate default constructor available
Thank you for your time!
It looks like the C++ specification specifically allows the first case and disallows the second!
Quote from the C++ spec (§8.3.6/4):
For non-template functions, default arguments can be added in later declarations of a function in the same scope.
So it looks like for non-template functions, you can indeed introduce the default arguments later on. No idea why this doesn't work for templates, though!
The first case is allowed by standard; I remember that was asked by @Johannes and answered by @Nawaz. (Edit: Here is the related question).
Reason for not allowing the template
version is because template
functions are called only when instantiated explicitly. In your case, compiler looks at the declaration as,
test<int> t;
-->Edit: It might differ from compiler to compiler. In gcc it works fine.<--
Why it may not work in some compiler might be Since you are not explicitly instantiating as t(N)
, compiler will not be able to resolve test<T>::test(int n = 666)
. Thus it looks for default constructor with no argument, which is not found; thus resulting in error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With