2016-02-26 30 views
7

Tworzę prostą klasę Matrix. Próbuję dodać anonimowego parametr szablonu, aby upewnić się, że stosowany jest z integralnych typachC++: Jak używać nienazwanych parametrów szablonu w elementach zajęć?

#include <string> 
#include <vector> 
#include <boost/utility/enable_if.hpp> 
#include <boost/type_traits/is_scalar.hpp> 

template <typename T, typename = typename boost::enable_if<boost::is_scalar<T> >::type> 
class Matrix 
{ 
    public: 
     Matrix(const size_t nrow, const size_t ncol); 

    private: 
     const size_t nrow_; 
     const size_t ncol_; 
     std::vector<std::string> rownames_; 
     std::vector<std::string> colnames_; 
     std::vector<T> data_; 
}; 

chciałbym zdefiniować konstruktor poza definicją klasy

template <typename T,typename> 
inline Matrix<T>::Matrix(size_t nrow, size_t ncol) 
    : nrow_(nrow), 
    ncol_(ncol), 
    rownames_(nrow_), 
    colnames_(ncol_), 
    data_(nrow_*ncol) 
{}; 

g ++ zwraca następujący błąd

Matrix.hh:25:50: error: invalid use of incomplete type ‘class Matrix<T>’ 
inline Matrix<T>::Matrix(size_t nrow, size_t ncol) 

Czy wiesz, jak rozwiązać ten problem?

Z góry dziękuję.

+0

Przez "zdefiniować na zewnątrz", co masz na myśli? W pliku cpp? – Garf365

+0

Nie, w nagłówku, zaraz po przecinku kończącym definicję klasy. –

Odpowiedz

5

Nazwy parametrów szablonów są "lokalne" dla każdej deklaracji szablonu. Nic nie przeszkadza ci w przypisaniu imienia. Co rzeczywiście musisz zrobić, jeśli chcesz odwołać się do tego parametru później (np. Użyć go jako argumentu w id szablonu klasy).

Tak więc, choć trzeba to w definicji klasy:

template <typename T, typename = typename boost::enable_if<boost::is_scalar<T> >::type> 
class Matrix 
{ 
    public: 
     Matrix(const size_t nrow, const size_t ncol); 

    private: 
     const size_t nrow_; 
     const size_t ncol_; 
     std::vector<std::string> rownames_; 
     std::vector<std::string> colnames_; 
     std::vector<T> data_; 
}; 

Można zdefiniować go poza klasą np tak:

template <typename AnotherName,typename INeedTheName> 
inline Matrix<AnotherName, INeedTheName>::Matrix(size_t nrow, size_t ncol) 
    : nrow_(nrow), 
    ncol_(ncol), 
    rownames_(nrow_), 
    colnames_(ncol_), 
    data_(nrow_*ncol) 
{}; 

Tylko nie zapomnij, że w ramach zwykłych okolicznościach templates can only be defined in header files.