2015-08-08 94 views
2

下面的代碼編譯。使用typedef for unique_ptr模板

模板之前matrix.h

template<typename T> 
class Matrix 
{ 
public: 
    //... 
    unique_ptr<Matrix<T>> Test() const; 
}; 

模板

template<typename T> 
unique_ptr<Matrix<T>> Matrix<T>::Test() const 
{ 
    unique_ptr<Matrix<T>> a{ new Matrix<T>{ 1, 1 } }; 
    return std::move(a); 
} 

之前matrix.cpp我想用一個typedef(使用)縮短的事情,因爲我認爲這會是更具可讀性,但我的更改會導致錯誤。這是相關的變化。

模板後matrix.h

template<typename T> 
class Matrix 
{ 
public: 
    //... 
    MatrixUniq<T> Test() const; 
}; 

template<class T> using MatrixUniq = unique_ptr<Matrix<T>>; 

後matrix.cpp模板

template<typename T> 
MatrixUniq<T> Matrix<T>::Test() const 
{ 
    MatrixUniq<T> a{ new Matrix<T>{ 1, 1 } }; 
    return std::move(a); 
} 

編譯這些更改後崩潰,VC++編譯器的兩倍,但也產生了一些錯誤:

Error C2143 syntax error: missing ';' before '<'  
Error C4430 missing type specifier - int assumed. 
Error C2238 unexpected token(s) preceding ';' 
Error C1903 unable to recover from previous error(s); 

我的typedef實現有什麼問題?謝謝。

編輯: 我正在使用VS2015。我正在建立一個靜態庫。在matrix.cpp的底部我:

template class VMatrix<double>; 

回答

4

您正在使用MatrixUniq<T>別名具有限定它。

移動using裏面的類:

template<typename T> 
class Matrix 
{ 
public: 
    template<class U> using MatrixUniq = std::unique_ptr<Matrix<U>>; 

    MatrixUniq<T> Test() const; 
}; 

並相應地改變了定義:

template<typename T> 
Matrix<T>::MatrixUniq<T> Matrix<T>::Test() const 
{ 
    return MatrixUniq<T>{ new Matrix<T>{ 1, 1 } }; 
} 

或者,如果你想擁有它的全局命名空間,類定義之後纔將其定義該類別的前向聲明:

template<typename T> 
class Matrix; 

template<class T> using MatrixUniq = std::unique_ptr<Matrix<T>>; 

template<typename T> 
class Matrix 
{ 
public: 
    //... 
    MatrixUniq<T> Test() const; 
}; 

另外你不需要在返回本地變量時明確地執行std::move。返回的局部變量默認會自動移動。

+0

我認爲你是對的。有沒有更短的做法,而不是冗長的矩陣 :: MatrixUniq 。最好是其他類可以在其他類中看到它的某種方式,我可以說:'MatrixUniq m = Foo();'? –

+0

@PhloxMidas請參閱我添加的關於直接在全局名稱空間中進行的編輯。 – emlai

+0

直接編譯。非常感謝你。 –

3

試試這個:

template<typename T> 
class Matrix 
{ 
public: 
    using unique_ptr_type = std::unique_ptr<Matrix>; 
    //... 
    unique_ptr_type Test() const; 
}; 

template<class T> using MatrixUniq = typename Matrix<T>::unique_ptr_type; 

template<typename T> 
typename Matrix<T>::unique_ptr_type Matrix<T>::Test() const 
{ 
    return unique_ptr_type(new Matrix()); 
} 
+0

謝謝您的回覆!它可能已經去了任何答案,我剛剛看到另一個答案,但我真的很感謝你的幫助。我投了贊成票。再次感謝。 –

+0

沒問題。接受的答案更完整。 –

1

務必確保在將要使用它的代碼上方聲明模板。

而且這個片段:

template<class T> using MatrixUniq = unique_ptr<Matrix<T>>; 

might not be a correct implementation. 

Here's how you can declare a type definition in c++. 

typedef <type> <var_name> 

下面是使用「別名模板」

template<typename T> 
using MyVector = std::vector<T, MyCustomAllocator<T>>; 

的代碼的其餘另一個例子是爲你調試。

這裏看到這個相關的討論:

How to typedef a template class?