2010-05-19 85 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