https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121172
Bug ID: 121172 Summary: error: use of 'static constexpr method...' before deduction of 'auto' WHEN upgrade to 15.1.0 : different writing order have different impact Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: terryinzaghi at 163 dot com Target Milestone: --- x86-64 g++15.1.0 -std=c++23 https://godbolt.org/z/sK5EdernP #include <cstdint> #include <cstddef> #include <type_traits> #include <utility> //--- This example can WORK in 14.2.0 14.3.0 , but failed in 15.1.0 template<typename... Ts> struct CanNotWork { template<int64_t I> constexpr auto operator/(int) const { return(CanNotWork<>{}); }; static constexpr auto static_method() {return 1;}; //--just return 1 template<typename... KeepItEmpty> using to_flike_t = decltype(static_method()); }; /* <source>:12:29: required from here 12 | return(CanNotWork<>{}); | ^ <source>:15:83: error: use of 'static constexpr auto CanNotWork<Ts>::static_method() [with Ts = {}]' before deduction of 'auto' 15 | template<typename... KeepItEmpty> using to_flike_t = decltype(static_method()); | ~~~~~~~~~~~~~^~ <source>:15:83: error: use of 'static constexpr auto CanNotWork<Ts>::static_method() [with Ts = {}]' before deduction of 'auto' <source>:15:83: error: use of 'static constexpr auto CanNotWork<Ts>::static_method() [with Ts = {}]' before deduction of 'auto' */ WORKROUND0: template<typename... Ts> struct CanWork0 { template<int64_t I> constexpr auto operator/(int) const {return(CanWork0<>{});}; static constexpr auto static_lmbd=[] {return 1;}; //--change static_method to static_lambda will make it WORKED template<typename... KeepItEmpty> using to_flike_t = decltype(static_lmbd()); }; WORKROUND1: template<typename... Ts> struct CanWork1 { //template<int64_t I> constexpr auto operator/(int) const {return(CanNotWork<>{});}; MOVE it AFTER static_method will make it WORKED static constexpr auto static_method() {return 1;}; //--just return 1 template<int64_t I> constexpr auto operator/(int) const {return(CanWork1<>{});}; //HERE can WORK template<typename... KeepItEmpty> using to_flike_t = decltype(static_method()); }; int main() { }