https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116492
Bug ID: 116492 Summary: inherited constructors in subclass of std::expected can not be overridden Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mail at johslarsen dot net Target Milestone: --- Created attachment 59007 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59007&action=edit preprocessed file First of all, sorry I subclassed the standard library, and yes, I am perfectly aware that this is a very bad practice. As such the important part might not be a fix for this in particular, but that it could shed light on similar problems elsewhere The following code snippet compiled with gcc 12.1 (first with std::expected on godbolt) through 14.2 (and trunk) constructs obj by calling std::expected's constructor directly instead of the constructor defined in my_expected: #include <expected> class my_expected : public std::expected<int, const char*> { public: my_expected() : std::expected<int, const char*>::expected(42) {} using std::expected<int, const char*>::expected; }; int main() { my_expected obj; return *obj != 42; } Resulting in *obj being zero (instead of 42), and a non-zero exit value. This only happens with the using statement, but as far as I understand the C++ documentation the derived constructor should have been used instead: > [...] if an inherited constructor matches the signature of one of the > constructors > of Derived, it is hidden from lookup by the version found in Derived. > https://en.cppreference.com/w/cpp/language/using_declaration The same does not happen in clang, and in gcc with similar examples from other classes I have tried. g++ returns no errors or warnings with -Wall -Wextra and all the other flags you suggested. The attached preprocessed file was generated with g++ 14.2.1 20240805