Why doesn't my compiler recognise “Bond() = default;”?
up vote
23
down vote
favorite
Please look at this code
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}
When attempting to compile I get an error:
error C2280: 'Bond::Bond(void)': attempting to reference a deleted function".
It's not a "rule of 3" violation since I've added the default constructor back.
Why doesn't the compiler recognise Bond() = default;
?
c++ c++11
New contributor
add a comment |
up vote
23
down vote
favorite
Please look at this code
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}
When attempting to compile I get an error:
error C2280: 'Bond::Bond(void)': attempting to reference a deleted function".
It's not a "rule of 3" violation since I've added the default constructor back.
Why doesn't the compiler recognise Bond() = default;
?
c++ c++11
New contributor
1
I have other erroruninitialized const member in 'const int'
. When you initialize constant member no more error produced.
– serge
yesterday
1
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
1
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.
– Rakete1111
yesterday
3
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Compiler says Dr. No.
– Glorfindel
16 hours ago
add a comment |
up vote
23
down vote
favorite
up vote
23
down vote
favorite
Please look at this code
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}
When attempting to compile I get an error:
error C2280: 'Bond::Bond(void)': attempting to reference a deleted function".
It's not a "rule of 3" violation since I've added the default constructor back.
Why doesn't the compiler recognise Bond() = default;
?
c++ c++11
New contributor
Please look at this code
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}
When attempting to compile I get an error:
error C2280: 'Bond::Bond(void)': attempting to reference a deleted function".
It's not a "rule of 3" violation since I've added the default constructor back.
Why doesn't the compiler recognise Bond() = default;
?
c++ c++11
c++ c++11
New contributor
New contributor
edited 23 hours ago
Peter Mortensen
13.2k1983111
13.2k1983111
New contributor
asked yesterday
Sasidiran Sangamanautram
1165
1165
New contributor
New contributor
1
I have other erroruninitialized const member in 'const int'
. When you initialize constant member no more error produced.
– serge
yesterday
1
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
1
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.
– Rakete1111
yesterday
3
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Compiler says Dr. No.
– Glorfindel
16 hours ago
add a comment |
1
I have other erroruninitialized const member in 'const int'
. When you initialize constant member no more error produced.
– serge
yesterday
1
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
1
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.
– Rakete1111
yesterday
3
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Compiler says Dr. No.
– Glorfindel
16 hours ago
1
1
I have other error
uninitialized const member in 'const int'
. When you initialize constant member no more error produced.– serge
yesterday
I have other error
uninitialized const member in 'const int'
. When you initialize constant member no more error produced.– serge
yesterday
1
1
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
1
1
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.– Rakete1111
yesterday
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.– Rakete1111
yesterday
3
3
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Compiler says Dr. No.
– Glorfindel
16 hours ago
Compiler says Dr. No.
– Glorfindel
16 hours ago
add a comment |
3 Answers
3
active
oldest
votes
up vote
43
down vote
The default constructor is suppressed since there are constant members that need to be explicitly initialised.
Therefore, due to that suppression, writing Bond() = default
does not reintroduce the default constructor.
(You can see this effect by removing all the constructors in the class - you still can't instantiate a b
.)
If you drop the const
from the members then all will be well.
add a comment |
up vote
20
down vote
Another fix, is to specify a default value in the declaration of the constants:
const int payments_per_year = {12};
This can still be overridden by the valued constructor, but allows the default constructor to proceed.
This is also a very flexible way to simplify your multiple constructor cases.
Do we need the braces?
– Paul Sanders
yesterday
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
add a comment |
up vote
11
down vote
You are being affected by section [class.default.ctor]p2 of the draft C++ standard (or [class.ctor]p5 in C++11) which says:
A defaulted default constructor for class X is defined as deleted if:
...
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
...
They possible key to fixing your issue is with the phrase with no brace-or-equal-initializer so if you provide brace-or-equal-initializer that will fix your issue e.g.:
const int payments_per_year{12};
const int period_length_in_months{48};
brace-or-equal-initializer does not require braces, we can see this the grammar:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
but using uniform initialization has some advantages such as making narrowing conversions ill-formed that it is worth getting used to using them.
Both gcc and clang provide more meaningful diagnostics for this see the live godbolt session. Sometimes it can be helpful to try your code on multiple compilers, especially if you have a minimal test case like this e.g. clang says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
43
down vote
The default constructor is suppressed since there are constant members that need to be explicitly initialised.
Therefore, due to that suppression, writing Bond() = default
does not reintroduce the default constructor.
(You can see this effect by removing all the constructors in the class - you still can't instantiate a b
.)
If you drop the const
from the members then all will be well.
add a comment |
up vote
43
down vote
The default constructor is suppressed since there are constant members that need to be explicitly initialised.
Therefore, due to that suppression, writing Bond() = default
does not reintroduce the default constructor.
(You can see this effect by removing all the constructors in the class - you still can't instantiate a b
.)
If you drop the const
from the members then all will be well.
add a comment |
up vote
43
down vote
up vote
43
down vote
The default constructor is suppressed since there are constant members that need to be explicitly initialised.
Therefore, due to that suppression, writing Bond() = default
does not reintroduce the default constructor.
(You can see this effect by removing all the constructors in the class - you still can't instantiate a b
.)
If you drop the const
from the members then all will be well.
The default constructor is suppressed since there are constant members that need to be explicitly initialised.
Therefore, due to that suppression, writing Bond() = default
does not reintroduce the default constructor.
(You can see this effect by removing all the constructors in the class - you still can't instantiate a b
.)
If you drop the const
from the members then all will be well.
answered yesterday
Bathsheba
172k26241365
172k26241365
add a comment |
add a comment |
up vote
20
down vote
Another fix, is to specify a default value in the declaration of the constants:
const int payments_per_year = {12};
This can still be overridden by the valued constructor, but allows the default constructor to proceed.
This is also a very flexible way to simplify your multiple constructor cases.
Do we need the braces?
– Paul Sanders
yesterday
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
add a comment |
up vote
20
down vote
Another fix, is to specify a default value in the declaration of the constants:
const int payments_per_year = {12};
This can still be overridden by the valued constructor, but allows the default constructor to proceed.
This is also a very flexible way to simplify your multiple constructor cases.
Do we need the braces?
– Paul Sanders
yesterday
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
add a comment |
up vote
20
down vote
up vote
20
down vote
Another fix, is to specify a default value in the declaration of the constants:
const int payments_per_year = {12};
This can still be overridden by the valued constructor, but allows the default constructor to proceed.
This is also a very flexible way to simplify your multiple constructor cases.
Another fix, is to specify a default value in the declaration of the constants:
const int payments_per_year = {12};
This can still be overridden by the valued constructor, but allows the default constructor to proceed.
This is also a very flexible way to simplify your multiple constructor cases.
answered yesterday
Gem Taylor
1,670216
1,670216
Do we need the braces?
– Paul Sanders
yesterday
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
add a comment |
Do we need the braces?
– Paul Sanders
yesterday
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
Do we need the braces?
– Paul Sanders
yesterday
Do we need the braces?
– Paul Sanders
yesterday
2
2
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
Equals and braces is definitely weird. Not sure what it actually means. Init from an initializer_list? Anyway: in-class member initializers are – well – initializers, and the syntax rules for initialization apply. That means either = or {}.
– besc
yesterday
6
6
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
@PaulSanders no, you don't need braces but uniform initialization has a lot of advantages such as making narrowing conversions ill-formed that it is worth getting used to using them. See my update below.
– Shafik Yaghmour
yesterday
3
3
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@ShafikYaghmour: You could keep the braces and drop the equal though.
– Matthieu M.
yesterday
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
@MatthieuM. that is exactly what I did in my answer.
– Shafik Yaghmour
8 hours ago
add a comment |
up vote
11
down vote
You are being affected by section [class.default.ctor]p2 of the draft C++ standard (or [class.ctor]p5 in C++11) which says:
A defaulted default constructor for class X is defined as deleted if:
...
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
...
They possible key to fixing your issue is with the phrase with no brace-or-equal-initializer so if you provide brace-or-equal-initializer that will fix your issue e.g.:
const int payments_per_year{12};
const int period_length_in_months{48};
brace-or-equal-initializer does not require braces, we can see this the grammar:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
but using uniform initialization has some advantages such as making narrowing conversions ill-formed that it is worth getting used to using them.
Both gcc and clang provide more meaningful diagnostics for this see the live godbolt session. Sometimes it can be helpful to try your code on multiple compilers, especially if you have a minimal test case like this e.g. clang says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
add a comment |
up vote
11
down vote
You are being affected by section [class.default.ctor]p2 of the draft C++ standard (or [class.ctor]p5 in C++11) which says:
A defaulted default constructor for class X is defined as deleted if:
...
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
...
They possible key to fixing your issue is with the phrase with no brace-or-equal-initializer so if you provide brace-or-equal-initializer that will fix your issue e.g.:
const int payments_per_year{12};
const int period_length_in_months{48};
brace-or-equal-initializer does not require braces, we can see this the grammar:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
but using uniform initialization has some advantages such as making narrowing conversions ill-formed that it is worth getting used to using them.
Both gcc and clang provide more meaningful diagnostics for this see the live godbolt session. Sometimes it can be helpful to try your code on multiple compilers, especially if you have a minimal test case like this e.g. clang says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
add a comment |
up vote
11
down vote
up vote
11
down vote
You are being affected by section [class.default.ctor]p2 of the draft C++ standard (or [class.ctor]p5 in C++11) which says:
A defaulted default constructor for class X is defined as deleted if:
...
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
...
They possible key to fixing your issue is with the phrase with no brace-or-equal-initializer so if you provide brace-or-equal-initializer that will fix your issue e.g.:
const int payments_per_year{12};
const int period_length_in_months{48};
brace-or-equal-initializer does not require braces, we can see this the grammar:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
but using uniform initialization has some advantages such as making narrowing conversions ill-formed that it is worth getting used to using them.
Both gcc and clang provide more meaningful diagnostics for this see the live godbolt session. Sometimes it can be helpful to try your code on multiple compilers, especially if you have a minimal test case like this e.g. clang says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
You are being affected by section [class.default.ctor]p2 of the draft C++ standard (or [class.ctor]p5 in C++11) which says:
A defaulted default constructor for class X is defined as deleted if:
...
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
...
They possible key to fixing your issue is with the phrase with no brace-or-equal-initializer so if you provide brace-or-equal-initializer that will fix your issue e.g.:
const int payments_per_year{12};
const int period_length_in_months{48};
brace-or-equal-initializer does not require braces, we can see this the grammar:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
but using uniform initialization has some advantages such as making narrowing conversions ill-formed that it is worth getting used to using them.
Both gcc and clang provide more meaningful diagnostics for this see the live godbolt session. Sometimes it can be helpful to try your code on multiple compilers, especially if you have a minimal test case like this e.g. clang says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
edited yesterday
answered yesterday
Shafik Yaghmour
122k23304504
122k23304504
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
add a comment |
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
It may be worth filing a bug report, the diagnostic could be more meaningful.
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
Some examples of [uniform initialization catching bugs that came up recently](twitter.com/shafikyaghmour/status/1058737227184844800
– Shafik Yaghmour
yesterday
add a comment |
Sasidiran Sangamanautram is a new contributor. Be nice, and check out our Code of Conduct.
Sasidiran Sangamanautram is a new contributor. Be nice, and check out our Code of Conduct.
Sasidiran Sangamanautram is a new contributor. Be nice, and check out our Code of Conduct.
Sasidiran Sangamanautram is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53225106%2fwhy-doesnt-my-compiler-recognise-bond-default%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
I have other error
uninitialized const member in 'const int'
. When you initialize constant member no more error produced.– serge
yesterday
1
Rule of three violation has got nothing to do with the problem at all, regardless of the presence of a (default) constructor.
– Konrad Rudolph
yesterday
1
= default
ing a special member doesn't mean that it exists, but that the implicit one is generated. If the implicitly generated one doesn't exist, then you get this.– Rakete1111
yesterday
3
Even though we are quite likely to recognize the compiler from the error cited in this case, any question with "why my compiler" would benefit greatly from indicating which compiler, and which version of it.
– Matthieu M.
yesterday
Compiler says Dr. No.
– Glorfindel
16 hours ago