Default constructor defined with default arguments

2019-06-18 20:12发布

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!

2条回答
闹够了就滚
2楼-- · 2019-06-18 20:32

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!

查看更多
Deceive 欺骗
3楼-- · 2019-06-18 20:32

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.

查看更多
登录 后发表回答