Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: How to use unnamed template parameters in class members?

I am creating a simple Matrix class. I am trying to add an unnamed template parameter to make sure it is used with integral types

#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_;
};

I would like to define the constructor outside the class definition

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++ returns the following error

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

Do you know how to solve this issue?

Thanks in advance.

like image 342
Florian Plaza Oñate Avatar asked Feb 26 '16 12:02

Florian Plaza Oñate


1 Answers

Template parameter names are "local" to each template declaration. Nothing prevents you from assigning a name. Which you indeed must do if you need to refer to that parameter later (such as using it as an argument in the template-id of the class).

So, while you have this in the class definition:

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_;
};

You can define it outside the class e.g. like this:

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)
{};

Just do not forget that under common circumstances, templates can only be defined in header files.

like image 177
Angew is no longer proud of SO Avatar answered Oct 24 '22 13:10

Angew is no longer proud of SO