0
#include <iostream>

using namespace std;

class A
{
private:
    float data_member;
public:
    A(int a);
    explicit A(float d);
};


A::A(int a)
{
    data_member = a;
}

A::A(float d)
{
    data_member = d;
}

void Test(A a)
{
    cout<<"Do nothing"<<endl;
}

int main()
{
    Test(12);
    Test(12.6); //Expecting a compile time error here
    return 0;
}

I am expecting a error int this case as my CTOR that takes float value is explicit. But I am not getting any error in VS 2010. Please point me out if I am wrong with my understanding of keyword "EXPLICIT" in c++.

Apoorva sahay
  • 1,900
  • 3
  • 28
  • 45

1 Answers1

4
explicit A(float d);

Does not do you think it does. It disables the implicit conversion from float to the type A. In short, It disables any implicit conversion wherein a float will be implicitly converted to a object of A. For ex:

void doSomething(A obj){}

doSomething(2.3);

It does not disable any implicit conversions allowed by the standard.


Why does it compile?

Test(12.6);

Because the float parameter is implicitly converted to int. What happens behind the scenes is same as:

float a = 12.6;
int   b = (int)a;

Further, the conversion constructor A::A(int a) is used to create a object of type A which is passed to the method Test().


Why does it not compile if you remove the explicit?

Without the keyword explicit the conversion constructor A::A(float d) is available for conversions and this creates a ambiguity because there are two possible matches, when converting 12.6 to object of type A:

A::A(int a)

or

A::A(float d)

Since none scores over other in terms of best match, the compiler emits the diagnostic of ambiguity.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • But how I am getting a compile time error for 2nd line in main function. – Apoorva sahay May 03 '13 at 05:18
  • @Apoorvasahay by removing explicit, you can get compile time error – Linga May 03 '13 at 05:19
  • @ling.s then what is the use of explicit keyword. As far as I know explicit keyword should be used to disable implicit conversion. My aim is not to make this code compilable, but to understand the usage of explicit keyword. – Apoorva sahay May 03 '13 at 05:23
  • 2
    @Apoorvasahay, With no explicit, it can either do an implicit standard conversion to `int` or to `float`. Both are equally valid, so overload resolution will fail. With the `explicit` there, it can only go for the `int` one implicitly. As for what it's good for, imagine a function taking a `std::vector`. Now imagine you call it with an argument of 3. If the size constructor was not explicit, that would be really unintuitive for it to compile like it would. – chris May 03 '13 at 05:23
  • @Alok Save So if I make my CTOR A::A(int a) as explicit then the compilation will not go through. And currently the code is compiling because the float is first converted to int and then compiler is calling A::A(int a). – Apoorva sahay May 03 '13 at 05:28
  • @Apoorvasahay: If you declare both conversion constructors as `explicit`, there is no conversion available from `float` to `A`, hence you will get a error. If you declare float version as `explicit` then implicit conversion from `float` to `int` takes place and then `int` version of constructor is used. – Alok Save May 03 '13 at 05:33