5

In the below code I am trying to use CRTP to use the static member "value" from the Child class in the Parent class. When compiling the code with g++ 5.2.1 with the "-pedantic" flag, I am able to compile as expected, and on execution both c.print_value(); and Child<int,4>::print_value(); print out 4.

#include <iostream>

template <typename DE>
struct Parent
{
    static const int value = DE::value;
    static void print_value ()
    {
        std::cout << "Value : " << value << '\n';
    }
};

template <typename T, int N>
struct Child : Parent< Child<T,N> >
{
    static const int value = N;
};

int
main ()
{
    Child<int,4> c;
    c.print_value();
    Child<int,4>::print_value();
}

However when compiling the same code with clang++3.7, I encounter compilation failures.

crtp_clang_error.cpp:9:32: error: no member named 'value' in 'Child<int, 4>'
static const int value = DE::value;
                       ~~~~^
crtp_clang_error.cpp:27:16: note: in instantiation of template class 'Parent<Child<int, 4> >' requested here
struct Child : Parent< Child<T,N> >
           ^
crtp_clang_error.cpp:38:16: note: in instantiation of template class 'Child<int, 4>' requested here
  Child<int,4> c;
           ^
crtp_clang_error.cpp:40:3: error: no member named 'print_value' in 'Child<int, 4>'; did you mean 'Parent<Child<int, 4> >::print_value'?
  Child<int,4>::print_value();
  ^~~~~~~~~~~~~~~~~~~~~~~~~
  Parent<Child<int, 4> >::print_value
crtp_clang_error.cpp:11:15: note: 'Parent<Child<int, 4> >::print_value' declared here
  static void print_value ()

I am not sure if this a Clang++ bug or a GCC hack. Would very much appreciate some insights.

drd_82
  • 61
  • 3
  • 2
    You inherit from `Parent< Child >`, at this point `Child` is still an incomplete type. Normally, you can't use typedefs, or members from the derived class in the CRTP base class body, see [this answer](http://stackoverflow.com/a/2749029/996886) for example, so I wouldn't expect it to work with a static member... but I'm not certain :) – melak47 Mar 02 '16 at 22:40
  • @melak47 I agree and that is exactly the error (incomplete type) that I encounter if I try this code with icc 14.0.2. So I would expect the behaviour of icc and clang++ to be valid. Wonder why g++ 5.2.1 does not complain. – drd_82 Mar 02 '16 at 23:02
  • 2
    Hm, `Parent::value` is only used at runtime. If you add something that requires the value at compile-time, you get the incomplete type error from GCC as well: [coliru](http://coliru.stacked-crooked.com/a/c0da629ab0061534). Might be a difference in how GCC and Clang treat initialization of static const variables? – melak47 Mar 02 '16 at 23:09
  • @melak47 Nice catch. That makes much more sense now. – drd_82 Mar 02 '16 at 23:28

0 Answers0