1

Can anyone explain why the following code compiles? I expect it to get an error where the double constant 3.3 can not be converted to int, since I declare the constructor to be explicit.

class A
{
public:
    int n;
    explicit A(int _n);
};

A::A(int _n)
{
    n = _n;
}

int main()
{
    A a(3.3); // <== I expect this line to get an error.
    return 0;
}
Robin Hsu
  • 4,164
  • 3
  • 20
  • 37
  • 9
    I think you might have misunderstood what the [explicit](http://en.cppreference.com/w/cpp/language/explicit) keyword does. – Mohamad Elghawi Dec 07 '15 at 08:57
  • 2
    Nope, this line will give you error `A b = 24;` – vishal Dec 07 '15 at 09:03
  • This is what uniform (i.e. brace-enclosed) initialization is for: `A a{3.3};` would fail because it's a narrowing conversion (double to int). However `A a(3.3);` does not because narrowing conversions are allowed. – KyleKnoepfel Dec 07 '15 at 12:25

2 Answers2

3

It works in the other way around. Let's define in addition to your code

void f(A a)
{
}

int main()
{
    A a(3.3); // <== I expect this line to get an error.
    f(5);
    return 0;
}

Without the word explicit it would compile, with the explicit it would report an error. The keyword forbids casting from integer to A in situations like this.

karastojko
  • 1,156
  • 9
  • 14
2

explicit class_name ( params ) (1)
explicit operator type ( ) (since C++11) (2)

1) specifies that this constructor is only considered for direct initialization (including explicit conversions)

2) specifies that this user-defined conversion function is only considered for direct initialization (including explicit conversions)

In your case you are using direct initialization to construct an instance of type A by doing this:

A a(3.3);

The explicit keyword does not stop the compiler from implicitly casting your argument from a double type to an int. It stops you from doing something like this:

A a = 33;
Mohamad Elghawi
  • 2,071
  • 10
  • 14