2
#include <iostream>

using namespace std;

class Test
{
private:
    mutable int val{};
public:
    static constexpr int MAX{ 5 };
public:
    Test() = default;
    Test(int i) : val{ i } {}
    ~Test() { cout << "~Test()" << endl; }

    explicit operator int() const { return val; }   // int()변환 연산자 오버로딩 (반환형식을 기재하지 않는다.)

    void print() const
    {
        ++val;  // mutable 형식이기 때문에 수정가능
        cout << val << endl;
    }
};

int main()
{
    Test t{ 10 };
    int i = static_cast<int>(t);    // int()변환 연산자가 explicit이라 명시적으로 타입캐스팅을 해주어야한다.
    int j{ t };                     // 근데 얘는 왜 될까..??
}

"Uniform initialization occurs implicitly, even though the int cast operator is declared with the explicit keyword. What is the reason?"

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
김정연
  • 47
  • 2

1 Answers1

1

int j{ t }; performs direct initialization, which does consider explicit conversion function.

Direct-initialization is more permissive than copy-initialization: copy-initialization only considers non-explicit constructors and non-explicit user-defined conversion functions, while direct-initialization considers all constructors and all user-defined conversion functions.

On the ohter hands, copy initialization only considers non-explicit conversion functions. Then int j = t; is ill-formed.

From the standard, [class.conv.fct]/2

A conversion function may be explicit ([dcl.fct.spec]), in which case it is only considered as a user-defined conversion for direct-initialization ([dcl.init]). Otherwise, user-defined conversions are not restricted to use in assignments and initializations. [ Example:

class Y { };
struct Z {
  explicit operator Y() const;
};

void h(Z z) {
  Y y1(z);          // OK: direct-initialization
  Y y2 = z;         // ill-formed: copy-initialization
  Y y3 = (Y)z;      // OK: cast notation
}

void g(X a, X b) {
  int i = (a) ? 1+a : 0;
  int j = (a&&b) ? a+b : i;
  if (a) {
  }
}

— end example ]

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • There is no explicit casting declaration in direct initialization, which part is explicit? – 김정연 Sep 26 '19 at 08:10
  • @김정연 Yes, you can think *direct initialization* as a kind of [explicit conversion](https://en.cppreference.com/w/cpp/language/explicit_cast). – songyuanyao Sep 26 '19 at 10:05