https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117392
Bug ID: 117392 Summary: template argument deduction problem with CNTTP Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: hanicka at hanicka dot net Target Milestone: --- Link to code and comparison with clang: https://compiler-explorer.com/z/zaqjYzfs4 In this a bit convoluted code I found while working on `P2781R4 std::constant_wrapper` When inside operators::operator- I tried to instantiate constant_wrapper<42u> (with unsigned int) ```c++ template <typename T> struct fixed_value { T data; using type = T; constexpr fixed_value(type v) noexcept: data(v) { } }; template <fixed_value Value, typename AdlType = decltype(Value)::type> struct constant_wrapper; ``` It fails because decltype(Value) is `unsigned int` and not `fixed_value<unsigned int>` If I replace `= decltype(Value)::type` with `= void` the link / code is working. ```c++ template <typename T> struct fixed_value { T data; using type = T; constexpr fixed_value(type v) noexcept: data(v) { } }; // if I use following line it will work // it seems when it's trying to instantiate `constant_wrapper` // it's using `Value` as parametr (of unsigned int) and not argument of type `fixed_value<unsigned int>` // and because of that the `decltype(Value)::type` fails // template <fixed_value Value, typename AdlType = void> template <fixed_value Value, typename AdlType = decltype(Value)::type> struct constant_wrapper; struct operators { template <typename L, typename R> friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)> { return {}; } }; template <fixed_value Value, typename AdlType> struct constant_wrapper: operators { static constexpr auto & value = Value.data; }; constexpr auto x = constant_wrapper<42u>{} - constant_wrapper<12>{}; ```