2010-05-19 117 views
2

下面这段代码不能编译,问题出在T::rank以上,在父模板中不能无法访问(我认为)或未初始化。C++ CRTP(模板模式)问题

你能告诉我到底是什么问题吗? 明确通过排名唯一的方式?或者有没有办法直接查询张量类?

谢谢

#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 

我知道了解决方法,但我感兴趣的模板实例化的机制进行自我教育

+0

它可能与我在visual studio中发现的这个错误有关吗? http://connect.microsoft.com/VisualStudio/feedback/details/354162/seemingly-valid-dependant-types-in-nested-template-not-accepted – 2010-05-19 05:01:02

+0

@kirill g ++ 4.3。我忘了添加实例化的最后一行,现在修复 – Anycorn 2010-05-19 05:01:19

+0

@evan它看起来确实相似 – Anycorn 2010-05-19 05:04:27

回答

2

在CRTP的基类模板利用了成员函数体(定义)在其声明之后很长时间才被实例化的事实。在你的代码中,基类依赖于不完整的类型。

+0

这个答案的确是对的。它导致'T :: rank'的SFINAE失败(因为':: rank'成员还没有被声明),因为实例化的点在'tensor <4>'的实例化点之前。查看http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287了解相关问题。 – 2010-05-19 18:29:34

2

我是唯一一个看着这里无限递归?

  • tensor<N,T>取决于tensor_operator< tensor<N,T> >
  • tensor_operator< tensor<N,T> >取决于tensor<N,T>

我不记得在那里我用了一个Derived类属性来决定是否要实例Base的情况,但它似乎对我来说这样会导致发生无限递归。

这里是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>' 

这里的问题似乎是的tensor_operator<N,T>实例化取决于tensor_operator<N,T>实例化...

+1

我不认为它是递归问题。我想可能是因为在父模板被实例化之后指定了rank,它根本就不在那里? – Anycorn 2010-05-19 17:18:06