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() {


}

Reply via email to