https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119008
Bug ID: 119008 Summary: for token(>): compiler can NOT distinguish close-template-block(>) from operator(>): Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: terryinzaghi at 163 dot com Target Milestone: --- the full code here: https://godbolt.org/z/KPjhWGGxa ---------------------------------------------------- BREIF: /* GT > example can work: using paren (...) to wrap the gt-op > */ template<typename TagT, typename... MemberTs> concept concept_is_good_write_order2 = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( (sizeof(T) > sizeof(NexT)) ) { //================ WORK return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; /* GT > example can NOT work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ template<typename TagT, typename... MemberTs> concept BAD_concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( sizeof(T) > sizeof(NexT)) { //================ FAIL <source>:107:40: error: expected ')' before '>' token return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; FOR LT(<), ITS OK, NOT need paren(...): /* COMPARE with LT: < */ template<typename TagT, typename... MemberTs> concept TEST_LT = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( sizeof(T) < sizeof(NexT)) { //------------WORK: < return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; ---------------------------------------------------- FULL CODE: #include <cstdint> #include <concepts> #include <type_traits> /* PREPARE CODE: these struct and functions implement are NOT important, they just to make this example can be compiled */ template<auto V> struct value_identity { static constexpr auto value = V;}; template<typename T> struct type_identity { using type = T;}; // for clang , gcc just use std::type_identity template< auto VerifyLmbd, std::size_t I, typename T0, typename T1, typename... UnhandledTs > static constexpr bool __ordered_window2_step1_conjunction_verify_f() { constexpr bool Cond = VerifyLmbd(type_identity<T0>{}, value_identity<I>{}, type_identity<T1>{}, value_identity<I+1>{}); if constexpr(Cond) { if constexpr(sizeof...(UnhandledTs) ==0) { return true; } else { return(__ordered_window2_step1_conjunction_verify_f<VerifyLmbd,I+1,T1,UnhandledTs...>()); } } else { return false; } }; template< auto VerifyLmbd, typename T, typename... UnhandledTs > static constexpr bool _ordered_window2_step1_conjunction_verify_f() { if constexpr(sizeof...(UnhandledTs) ==0) { return true; } else { return(__ordered_window2_step1_conjunction_verify_f<VerifyLmbd,0,T,UnhandledTs...>()); } }; template< auto VerifyLmbd, // [] -- window count 2 : prev , current; iter advance step 1 ; // < // typename EleT0, size_t Index0, // typename EleT1, size_t Index1, // >( // std::type_identity<EleT0>, value_identity<Index0>, // std::type_identity<EleT1>, value_identity<Index1>, // ) -> bool typename... UnhandledTs > requires(sizeof...(UnhandledTs) >0) static constexpr bool ordered_window2_step1_conjunction_verify_v =_ordered_window2_step1_conjunction_verify_f<VerifyLmbd,UnhandledTs...>(); /* GT > : example can work: using a variable */ template<typename TagT, typename... MemberTs> concept concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { constexpr bool CondGt = (sizeof(T) > sizeof(NexT)) ; //... if constexpr ( CondGt ) { //================ WORK return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; /* GT > example can work: using paren (...) to wrap the gt-op > */ template<typename TagT, typename... MemberTs> concept concept_is_good_write_order2 = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( (sizeof(T) > sizeof(NexT)) ) { //================ WORK return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; /* GT > example can NOT work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ template<typename TagT, typename... MemberTs> concept BAD_concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( sizeof(T) > sizeof(NexT)) { //================ FAIL <source>:107:40: error: expected ')' before '>' token return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; /* COMPARE with LT: < */ template<typename TagT, typename... MemberTs> concept TEST_LT = ordered_window2_step1_conjunction_verify_v< []<typename T, std::size_t I,typename NexT, std::size_t NexI>( std::type_identity<T>, value_identity<I>, std::type_identity<NexT>,value_identity<NexI> )->bool { //... if constexpr ( sizeof(T) < sizeof(NexT)) { //------------WORK: < return true; } else if constexpr ( sizeof(T) == sizeof(NexT) ) { return(alignof(T) >= alignof(NexT)); } else { return false; } //... }, MemberTs... >() && !std::is_same_v<TagT,void>; int main() { };