Template argument deduction order

c++, c++11, templates

Solution

There is no template argument deduction happening in your code, so this has nothing to do with deduction.

The problem is caused by trying to use members of `Derived` while it is an incomplete type.

The friend declarations are processed immediately by the compiler during the instantiation of `Base<Derived<U,D,T>>` which occurs in the base class list of `Derived`, and at that point `Derived` is incomplete, so trying to use its members is not possible.

The static member in `Sum` is not instantiated automatically, and isn't needed in the declaration of `Triple`. If you use the static member later on then `Triple` is a complete type and its members can be referred to.

If you try to use `Sum<T>::sze` in the definition of `Sum` you will get a similar error, because `T` is not a complete type at that point:

template <typename T>
struct Sum
{
    constexpr static int sze = T::uno + T::due + T::tre;
    char buf[sze];
};

template<int i, int j, int k>
struct Triple : public Sum<Triple<i, j, k>>
{
    constexpr static int uno = i;
    constexpr static int due = j;
    constexpr static int tre = k;
};

Triple<1, 2, 3> t;

Problem

Can anybody explain why the following code does not compile: ``` template <typename P> struct Base { friend typename P::One; friend typename P::Two; friend typename P::Three; }; template<typename U, typename D, typename T> struct Derived : public Base<Derived<U,D,T>> { using One = U; using Two = D; using Three = T; }; ``` The error is: ``` ..\PRP\main.cpp:3:1: error: no type named 'One' in 'struct Derived<A, B, C>' { ^ ..\PRP\main.cpp:3:1: error: no type named 'Two' in 'struct Derived<A, B, C>' ..\PRP\main.cpp:3:1: error: no type named 'Three' in 'struct Derived<A, B, C>' ``` And why the following code compile perfectly: ``` template <typename T> struct Sum { constexpr static int sze = T::uno + T::due + T::tre; }; template<int i, int j, int k> struct Triple : public Sum<Triple<i, j, k>> { constexpr static int uno = i; constexpr static int due = j; constexpr static int tre = k; }; ``` What are the differences between the two? I think it is something related to the template deduction order but I could be wrong. I'm using MinGW 4.8 on Win7 with flag C++11 on. Thanks!

Original source