http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57846
Bug ID: 57846 Summary: CRTP, templates, metaprogramming, forwarding and static member Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: vince.rev at gmail dot com This code (I could not find a simpler example) does not compile under g++ for some obscure reasons (tested with 4.8.1 and 4.7.2) (see the related discussion on stack overflow here : http://stackoverflow.com/questions/17515079/crtp-templates-metaprogramming-forwarding-and-static-member-a-bug-in-g-4-8): ------------------------------------------------------------- #include <iostream> #include <type_traits> #include <utility> #include <tuple> #include <array> template <class Crtp, class... Types> struct Base { template <unsigned int Index, class Type = typename std::tuple_element<Index, std::tuple<Types...> >::type> inline const Type& get() const {return std::get<Index>(data);} template <unsigned int Index, class Type = typename std::tuple_element<Index, std::tuple<Types...> >::type> inline Crtp& set(const Type& value) {std::get<Index>(data) = value; return static_cast<Crtp&>(*this);} std::tuple<Types...> data; }; template <typename Type, unsigned int Size> struct Derived : public Base<Derived<Type, Size>, std::array<Type, Size>> { template <class... Args, class Template = decltype(std::declval<const Base<Derived<Type, Size>, std::array<Type, Size>>>().template get<0>(std::declval<Args>()...))> inline Template test(Args&&... args) const {return this->template get<0>(std::forward<Args>(args)...);} template <class... Args, class Template = decltype(std::declval<const Base<Derived<Type, Size>, std::array<Type, Size>>>().template set<0>(std::declval<Args>()...))> inline Derived<Type, Size>& test(Args&&... args) {return this->template set<0>(std::forward<Args>(args)...);} static void check() {Derived<double, 3> derived; std::cout<<derived.test()[0]<<std::endl;} }; int main(int argc, char* argv[]) { Derived<double, 3> derived; std::cout<<derived.test()[0]<<std::endl; // Working Derived<double, 3>::check(); // Not working: error: no match for ‘operator[]’ (operand types are ‘Derived<double, 3u>’ and ‘int’) return 0; } -------------------------------------------------------------