views:

215

answers:

2

following piece of code does not compile, the problem is in T::rank not be inaccessible (I think) or uninitialized in parent template.

Can you tell me exactly what the problem is? is passing rank explicitly the only way? or is there a way to query tensor class directly?

Thank you

#include <boost/utility/enable_if.hpp>

template<class T, // size_t N,
         class enable = void>
struct tensor_operator;

// template<class T, size_t N>
template<class T>
struct tensor_operator<T, typename boost::enable_if_c< T::rank == 4>::type > {
    tensor_operator(T &tensor) : tensor_(tensor) {}
    T& operator()(int i,int j,int k,int l) {
        return tensor_.layout.element_at(i, j, k, l);
    }
    T &tensor_;
};

template<size_t N, typename T = double>
// struct tensor : tensor_operator<tensor<N,T>, N> {
struct tensor : tensor_operator<tensor<N,T> > {
    static const size_t rank = N;
};

 tensor <4> D;  // compiler attempts to instantiate undefined template, not specialization

I know the workaround, however am interested in mechanics of template instantiation for self-education

+2  A: 

Am I the only one looking at an infinite recursion here ?

  • tensor<N,T> depends on tensor_operator< tensor<N,T> >
  • tensor_operator< tensor<N,T> > depends on tensor<N,T>

I don't recall a situation where I used a Derived class property to decide whether or not to instantiate Base, but it does seem to me like this would cause infinite recursion to occur.

Here is the error on gcc 3.4.2:

 In instantiation of `tensor<4ul, double>':
41:   instantiated from here
33: error: invalid use of undefined type
                          `struct tensor_operator<tensor<4ul, double>, void>'
19: error: declaration of `struct tensor_operator<tensor<4ul, double>, void>'

The issue here seems to be that the instantiation of tensor_operator<N,T> depends on the instantiation of tensor_operator<N,T>...

Matthieu M.
I do not think it's recursion problem. I think maybe because rank is specified after parent template is instantiated, it is simply not there?
aaa
+2  A: 

In CRTP the base class template take advantage of the fact that member function bodies (definitions) are not instantiated until long after their declarations. In your code the base class depends on incomplete type.

Kirill V. Lyadvinsky
This answer is indeed correct. It causes an SFINAE failure for `T::rank` (because the `::rank` member has not yet been declared) because the point of instantiation is prior to the point of instantiation of `tensor<4>`. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287 for some insight into related issues.
Johannes Schaub - litb