https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68388

            Bug ID: 68388
           Summary: incomplete type bug when using decltype
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ryan.burn at gmail dot com
  Target Milestone: ---

The below code compiles fine with clang
(http://melpon.org/wandbox/permlink/Rm6dpbmC0N3eMJJa) and earlier versions of
gcc-6, but was recently broken. Gcc gives this error when compiling:

bug.cpp: In instantiation of ‘auto map_impl(std::index_sequence<Indexes ...>,
Functor, T1, T2) [with int ...Indexes = {0}; Functor = Less; T1 = Tuple<int>;
T2 = Tuple<int>]’:
bug.cpp:27:11:   required from ‘auto map_impl(Functor, T1, T2) [with Functor =
Less; T1 = Tuple<int>; T2 = Tuple<int>]’
bug.cpp:40:26:   required from here
bug.cpp:22:3: error: invalid use of incomplete type ‘class Tuple<decltype
(apply_impl<Indexes>(f, t1, t2))...>’
   Tuple<decltype(apply_impl<Indexes>(f, t1, t2))...>();
   ^~~~~

bug.cpp:8:27: note: declaration of ‘class Tuple<decltype
(apply_impl<Indexes>(f, t1, t2))...>’
 template <class...> class Tuple {};

///////////////////////////////////////////////////////////
typedef int size_t;                                                             
template <std::size_t... Indexes>                                               
struct index_sequence {};                                                       
}                                                                               


template <class...> class Tuple {};                                             

template <std::size_t I, class TFirst>                                          
auto get(Tuple<TFirst>) {                                                       
  return TFirst();                                                              
}                                                                               

template <std::size_t I, class Functor, class T1, class T2>                     
auto apply_impl(Functor f, T1 t1, T2 t2) {                                      
  return f(get<I>(t1), get<I>(t2));                                             
}                                                                               

template <std::size_t... Indexes, class Functor, class T1, class T2>            
auto map_impl(std::index_sequence<Indexes...>, Functor f, T1 t1, T2 t2) {       
  Tuple<decltype(apply_impl<Indexes>(f, t1, t2))...>();                         
}                                                                               

template <class Functor, class T1, class T2>                                    
auto map_impl(Functor f, T1 t1, T2 t2) {                                        
  map_impl(std::index_sequence<0>(), f, t1, t2);                                
}                                                                               

struct Less {                                                                   
  template <class Lhs, class Rhs>                                               
  auto operator()(Lhs lhs, Rhs rhs) -> decltype(lhs < rhs) {                    
    return lhs < rhs;                                                           
  }                                                                             
};                                                                              

int main() {                                                                    
  auto t1 = Tuple<int>();                                                       
  auto t2 = Tuple<int>();                                                       
  map_impl(Less(), t1, t2);                                                     
}
///////////////////////////////////////////////////////////

Reply via email to