98버전에도 있었고 과제를 배끼면서 하다가 스쳐지나갔기 때문에 제대로 알지 못했던 키워드이다.

explicit은 생성자에 묵시적 형변환을 막아주기 위해 존재하는 키워드이다. 특히 대입연산자 또는 함수에 파라미터로 들어갈 때 특정 class로 형변환이 될 수 있다. 이러한 변환을 막으려면 explicit 키워드를 생성자 앞에 붙여주면 된다. 가장 좋은 예시는 이것이다.

코드

#include <iostream>

class Base
{
    int mVar;
public:
    Base() {}
    Base(int var) : mVar(var) {}
    void print() { std::cout << mVar << std::endl; }
};

void printBase(Base base) {
    base.print();
}

int main()
{
    Base obj1(10);
    Base obj2 = 20; // <------ obj(20)인 것처럼 implicit casting

    printBase(obj1);
    printBase(30); // <------ printBase함수 안에서 30이 Base로 implicit casting
    return (0);
}


터미널

10
30

이렇게 묵시적 형변환이 되는 것을 자연스럽게 받아들이는 사람도 있을 수도 있을 것같고 아닌 사람도 많을 것이다.

나는 이런 묵시적 형변환이 부자연스럽게 느껴진다. 그래서 explicit 키워드가 생성자로의 묵시적 형변환을 막아줘서 좋은 키워드인 것같다.

explicit 적용 코드

#include <iostream>

class Base
{
    int mVar;
public:
    Base() {}
    explicit Base(int var) : mVar(var) {} // <------ 여기에 explicit 키워드만 추가하면?
    void print() { std::cout << mVar << std::endl; }
};

void printBase(Base base) {
    base.print();
}

int main()
{
    Base obj1(10);
    Base obj2 = 20;

    printBase(obj1);
    printBase(30);
    return (0);
}


터미널

explicit.cpp:19:10: error: no viable conversion from 'int' to 'Base'
    Base obj2 = 20;
         ^      ~~
explicit.cpp:3:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Base &' for 1st argument
class Base
      ^
explicit.cpp:8:14: note: explicit constructor is not a candidate
    explicit Base(int var) : mVar(var) {}
             ^
explicit.cpp:22:5: error: no matching function for call to 'printBase'
    printBase(30);
    ^~~~~~~~~
explicit.cpp:12:6: note: candidate function not viable: no known conversion from 'int' to 'Base' for 1st argument
void printBase(Base base) {
     ^
2 errors generated.


explicit 키워드를 복사 생성자에 붙여 위의 에러로 묵시적 형변환을 막았다.

에러메시지를 보면,

- int에서 Base로 형변환 불가
- 묵시적 복사 생성자가 가능하지 않다: int에서 const Base&로의 변환이 알려져있지 않다
- explicit constructor는 candidate가 아니다
- printBase와 대응되는 함수가 없다
- candidate function이 가능하지 않다: 첫번째 아규먼트가 int에서 Base로 알려져있지 않다

그런데, 위의 에러메시지 중 candidate constructor 키워드가 들어간 것을 해석하지 못하겠다. candidate constructor를 인터넷에 찾아봐도 정확히 이것이 XX이다 라는 정의가 안나온다. 그냥 생성자 예시를 든거라고 해석하면 될까? 의문이다…