Question Details

No question body available.

Tags

c++ language-lawyer c++23

Answers (1)

May 12, 2026 Score: 3 Rep: 45,734 Quality: Medium Completeness: 60%

When #1 is not deleted, there are thee candidates:

template  // [T = std::string]
struct optional {
    template  // [U = DBEntry&]
    requires(std::isconstructiblev)
    explicit(false) optional(U&&);  // Converting constructor
};

struct DBEntry { template // [T = std::optional] operator T() const; // Conversion operator #1

template // [T = std::string] operator std::optional() const; // Conversion operator #2 };

The converting constructor is better because it takes a DBEntry&, but both of the conversion operators' implicit object parameter have type const DBEntry, and the adding of const is a tiebreaker†.

When #1 is deleted, optional's converting constructor is no longer viable since its constraint is not satisfied. This is sort of orthogonal, the deleted conversion operator is picked (so overload resolution during isconvertiblev was not affected) which is the whole reason we can observe it is deleted. There is one less candidate, and #2 is chosen because it is more specialised.


† Note if you made the conversion operators non-const or had const DBEntry entry;, neither would be preferred and the conversion would be ambiguous