explicit (C++)

Prevents implicit type conversions, which might cause errors.

C++ ctors (constructors) that have just one parameter automatically perform implicit type conversion. For example, if you pass an int when the ctor expects a string pointer parameter, the compiler adds the code it must have to convert the int to a string pointer. However, this automatic behavior can cause errors.

To prevent implicit conversions, you can add the explicit keyword to the ctor declaration. This forces the code to either use a parameter of the correct type, or cast the parameter to the correct type. That is, if the cast is not explicitly expressed in code, an error will result.

The explicit keyword can only be applied to in-class ctor declarations to explicitly construct an object.

In general, we recommend that you mark all single-argument ctors explicit unless you are certain you want implicit conversions.

Example

Compiling the following program produces errors. The code tries to perform an implicit conversion, but the explicit keyword prevents it. To resolve the error, remove the explicit keywords and adjust the code in the g function.

// spec1_explicit.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;

class TestClass1 
{
public:
    int m_num;
    TestClass1()
    {
        m_num = 0;
    }
    explicit TestClass1(const TestClass1&)   // an explicit copy ctor
    {
        cout<< "in the TestClass1 copy ctor" << endl;
    }
    explicit TestClass1(int num)   // an explicit ctor
    {
        cout << "in the TestClass1 int ctor" << endl;
    }

};

class TestClass2
{
public:
    int m_num;
    explicit TestClass2(int num)   // an explicit ctor
    {
        cout << "in the TestClass2 int ctor" << endl;
    } 
};

TestClass1 func1(TestClass1 c)
{   
    c.m_num = 1;
    return c;   // Error C2558
}

void func2(TestClass2)
{
}

void g(int i)
{
    func2(i);   // Error C2664
    // try the following line instead
    func2(TestClass2(i));
}

int main()
{
    TestClass1 testA;
    TestClass1 testB;
    cout << "testA: " << testA.m_num << endl;
    cout << "testB: " << testB.m_num << endl;
    testB = func1(testA);   // testA is copied
    cout << "testB after func1(testA) call: " << testB.m_num << endl;
}

Declaring a ctor that has multiple arguments to be explicit has no effect, because such ctors cannot take part in implicit conversions. However, explicit does have an effect if a ctor has multiple arguments and all except one of them has a default value.

See Also

Reference

C++ Keywords

Conversions