While thinking how CRTP can be improved in C++11, I ended with the following code:
template <typename Derived, typename Delayer>
struct derived_value_type
{
typedef typename Derived::value_type type;
};
template <typename Derived>
struct base
{
template <typename Delayer = void>
typename derived_value_type<Derived, Delayer>::type
foo(){ return {}; }
};
struct derived : base<derived>
{
typedef int value_type;
};
#include <iostream>
#include <typeinfo>
int main()
{
derived d;
auto bar = d.foo();
std::cout << typeid(bar).name() << ':' << bar << std::endl;
}
I believe the previous code to be standard conformant, and it compiles and works with the major compilers (resulting in i:0
). However, when I use a template alias instead, I get a compilation error due to derived
being incomplete:
template <typename Derived, typename Delayer>
using derived_value_type = typename Derived::value_type;
/*...*/
template <typename Delayer = void>
derived_value_type<Derived, Delayer>
foo(){ return {}; }
Is this a compiler bug, or does the fact that the compiler can determinate that there is no real dependency with Delayer
mean that the template alias is not a dependent type? Where is this specified in the standard?