1

When I declare my copy constructor as explicit, calling it using = instead of () doesn't compile. Here's my code:

class Base
{
    public:
        explicit Base(){cout<<__PRETTY_FUNCTION__<<endl;}
        explicit Base(Base& b){cout <<__PRETTY_FUNCTION__<<endl;}
};

int main()
{
    Base a;
    Base b=a;
}

The compiler says:

error: no matching function for call to ‘Base::Base(Base&)’

If I change it to

Base b(a);

It compiles fine. I thought C++ considers these two styles of instantiations the same. If I remove the explicit keyword it does works both ways. I'm guessing there is some implicit conversion going on when I use =. So what am I missing here?

Syed H
  • 305
  • 1
  • 2
  • 9
  • 3
    They are not the same. One is direct-initialization, the other is copy-initialization. `explicit` constructors cannot be picked by the latter. – Andy Prowl Jan 18 '15 at 13:53
  • pls make your copy constructor take `const&` arguments – TemplateRex Jan 18 '15 at 13:55
  • 1
    It was originally, but the compiler error (above) was showing non-const. So just to eliminate that as a possibility I matched what the compiler was showing. – Syed H Jan 18 '15 at 14:01
  • @AndyProwl pls make your comment an _answer_ – Lightness Races in Orbit Jan 18 '15 at 15:07
  • @LightnessRacesinOrbit I thought it was very likely for this to be a duplicate, but did not have the time (or rather, did not bother - my bad) to look for an existing answer. I left a comment, hoping to be helpful enough. – Andy Prowl Jan 18 '15 at 15:41
  • @AndyProwl: Writing answers in comments encourages help vampirism and ruins the integrity of the Q&A format. SO is not a forum or chatroom!!!! – Lightness Races in Orbit Jan 18 '15 at 15:43

1 Answers1

3

No, they are not the same. C++ Standard section § 12.3.1 [class.conv.ctor]

An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used


Base b(a); // Direct initialization
Base b=a;  // Copy initialization

Copy initialization (using =) doesn't consider explicit constructors, but direct initialization (using ()) does.

You'll have to use a cast or make your constructor non explicit if you want to use copy initialization.

quantdev
  • 23,517
  • 5
  • 55
  • 88
  • So for non-built in types, is it same to assume that () always offers better performance than = since the latter tries to do an implicit conversion? – Syed H Jan 18 '15 at 14:12
  • 1
    @SyedH I invite you to read [this answer](http://stackoverflow.com/a/1051468/3510483) for a complete overview of the differences – quantdev Jan 18 '15 at 14:19
  • Ugh, there's a horrid editorial mistake in this standard text, present in C++11 and C++14 and the latest draft. – Lightness Races in Orbit Jan 18 '15 at 15:08
  • [I have reported it to `std-discussion`](https://isocpp.org/forums/iso-c-standard-discussion?place=topic%2Fstd-discussion%2F_SBNczqk-NM%2Fdiscussion). – Lightness Races in Orbit Jan 18 '15 at 15:13