Q:

Using typedefs of a non-template derived class in the base class when using CRTP

I'm using CRT pattern and want the base class to see typedefs from the derived class. In this post  @James McNellis suggested to do that using base_traits class and it works fine. But in the case described in that post the derived class itself is a template. This approach does not work in VS2010 when the derived class is not a template. 
template <class D>
struct base_traits;
template <class D>
struct base
{
    typedef typename base_traits<D>::value_t value_t;
};

struct derived : base<derived>
{
    typedef typename base_traits<derived>::value_t value_t;
};

template<>
struct base_traits<derived>
{
    typedef int value_t;
};

The above code gives lots of errors. The first one is:

error C2027: use of undefined type 'base_traits

on the line of the base class's typedef.

A:

base_traits<derived> must be declared and defined prior it's usage since it is needed for the implicit instancation of base<derived> (below, I forward declared derived) : 
template <class D>
struct base_traits;

template <class D>
struct base
{
    typedef typename base_traits<D>::value_t value_t;
};

struct derived;

template<>
struct base_traits<derived>
{
    typedef int value_t;
};

struct derived : base<derived>
{
    typedef base_traits<derived>::value_t value_t;
};

int main(void)
{
    derived d;
}

Live demo

A:

§14.7.3 [temp.expl.spec]/p7:

The placement of explicit specialization declarations for function
  templates, class templates, variable templates, member functions of
  class templates, static data members of class templates, member
  classes of class templates, member enumerations of class templates,
  member class templates of class templates, member function templates
  of class templates, static data member templates of class templates,
  member functions of member templates of class templates, member
  functions of member templates of non-template classes, static data
  member templates of non-template classes, member function templates of
  member classes of class templates, etc., and the placement of partial
  specialization declarations of class templates, variable templates,
  member class templates of non-template classes, static data member
  templates of non-template classes, member class templates of class
  templates, etc., can affect whether a program is well-formed according
  to the relative positioning of the explicit specialization
  declarations and their points of instantiation in the translation unit
  as specified above and below. When writing a specialization, be
  careful about its location; or to make it compile will be such a trial
  as to kindle its self-immolation.

In particular (§14.7.3 [temp.expl.spec]/p6),

If a template [...] is explicitly specialized then that specialization
  shall be declared before the first use of that specialization that
  would cause an implicit instantiation to take place, in every
  translation unit in which such a use occurs; no diagnostic is
  required. If the program does not provide a definition for an
  explicit specialization and [...] the specialization is used in a way
  that would cause an implicit instantiation to take place [...], 
  the program is ill-formed, no diagnostic required.

The explicit specialization base_traits<derived> must be declared and defined before the definition of derived, as otherwise both inheriting from base<derived> and using base_traits<derived>::value_t would trigger an implicit instantiation. Thus:
template <class D>
struct base_traits;

template <class D>
struct base
{
    typedef typename base_traits<D>::value_t value_t;
};

struct derived;

template<>
struct base_traits<derived>
{
    typedef int value_t;
};

struct derived : base<derived>
{
    typedef base_traits<derived>::value_t value_t;
};

