16

I found it quite odd that the following program still compiled fine despite the default constructor being private (4.8.1 g++):

 class A{
 private:
     A() = default;
     A(const A&) = default;
 };

 int main(){

     A a;

 }

Actually from 8.4.2[2] of the standard (N3242)

An explicitly-defaulted function may be declared constexpr only if it would have been implicitly declared as constexpr. If it is explicitly defaulted on its first declaration,

— it shall be public,

..........

What exactly is the purpose for the default specifier to ignore the access specification? I feel like that could cause an interface issue unwarranted by the class designer that didn't want users to create default values but needed the default constructor in the implementation. I thought that maybe it's because the default constructor is normally public and so the default aims to replicate it - but that doesn't answer why =default on the copy constructor doesn't ignore the private specification.

 class A{
 private:
     A() = default;
     A(const A&) = default;
 };

 int main(){

     A a;
     A b(a); //error: constexpr A::A(const A&) is private

 }

Actually I can't see from the standard where it mentions that explicitly-defaulted copy/move constructors/assignments aren't made public.

Community
  • 1
  • 1
Silversonic
  • 1,289
  • 2
  • 11
  • 26

1 Answers1

15

This is a gcc bug. Bug 57913 contains an example almost identical to yours. Bug 56429 contains links to several related bug reports, of which bug 54812 has been fixed in gcc 4.9, which indeed rejects your code.

error: 'constexpr A::A()' is private

Live demo

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Alrighty, thanks. I guess I misunderstood that quote from the standard. It was being completely specific to the context of `constexpr` declared functions. – Silversonic Oct 16 '15 at 22:03
  • 3
    @Silversonic Which version of the standard are you quoting? I can't find the *it shall be public* part in either N3337 or N4296 – Praetorian Oct 16 '15 at 22:06
  • I was looking at N3242. I thought that was the best one to look at if I was working with C++11? Should I swap to N3337? – Silversonic Oct 16 '15 at 22:12
  • 2
    @Silversonic N3337 is the first draft published after the ISO C++11 standard version (which is not free). Richard Smith says [here](http://stackoverflow.com/a/8323351/241631) that it only contains minor editorial differences from the published standard, so I'd switch to that rather than use a version from before publication. – Praetorian Oct 16 '15 at 22:18
  • 1
    @Silversonic [Here's](http://wg21.cmeerw.net/cwg/issue1135) the issue that brought about the change in wording from what you're quoting – Praetorian Oct 16 '15 at 22:19