Explicit conversion function in C++

Viewed 219

I have a code:

struct Conv;
struct Test {
    Test() {}
    Test(Test const& ref) = delete;
    Test(Test&& ref) = delete;
    Test(int) { puts("int"); }
};

struct Conv {
    explicit operator int() const {
        puts("operator Test()");
        return 7;
    }
};

int main() {
   Conv y;
   Test x {y}; // direct list initialization
}

It produces error:

clang: no matching constructor for initialization of 'Test' Test x {y};

gcc: no matching function for call to 'Test::Test(<brace-enclosed initializer list>)' 21 | Test x {y};

If I change from int() to Test(), the code works

struct Conv {
    explicit operator Test() const {
        puts("operator Test()");
        return 7;
    }
};

This works. If marked explicit compiler shouldn't do any implicit conversions? But why the second case works whereas the first doesn't?

1 Answers

why the operator Test() works? Because explicit operator declares a user-defined conversion function that participates in direct-initialization and explicit conversions only:

Test x1 {y};    // direct initialization  OK
Test x2 = static_cast<Test>(y);  // explicit conversion OK
//Test x3 = y;  // copy initialization Error
Related