Можно ли создать вектор шаблонного класса и вызвать его функции? - PullRequest
1 голос
/ 29 апреля 2020

Я создал шаблонный класс с некоторыми методами, которые используют в качестве типа шаблона параметра, например:

template <class T>
class vector{
... 
void new(const T&new_value)
...
}

Я хочу использовать его внутри другого класса, но так как ему запрещено объявлять его следующим образом:

class matrix{
vector *_ptr_to_vect;
}

Я создал базовый класс BaseVector.

Но в BaseVector я не могу определить виртуальную функцию, например new(const T&new_value), для ее переопределения (потому что я не хочу использовать шаблон снова). Так как я не могу определить это, то невозможно назвать это как:

BaseVector _ptr_to_vect;
BaseVector[0].new("new value")

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Вам не нужен базовый класс. Вам нужно сделать matrix шаблон:

template <class T>
class matrix{
    vector<T> _ptr_to_vect;
};

Альтернативно, если ваш класс матрицы всегда одного типа (например, float):

class matrix{
    vector<float> _ptr_to_vect;
};
0 голосов
/ 29 апреля 2020

Комментарий автора:

Проблема в том, что я хочу матрицу с разными типами. Например, 1-й столбец целых чисел, 2-й столбец с плавающей точкой и т. Д.

В чистом C ++ 11 для этой цели вы можете использовать битовый шаблон magi c:

//
// Lightweight wrapper over any type
//
template<typename T>
struct identity {
    using type = T;
};

//
// Metafunction that converts type T
// into vector<T>
//
template<typename T>
struct add_vector {
    using type = vector<T>;
};

//
// Function used to obtain std::tuple<vector<Types>>
// type from Types
//
template<typename... Types>
constexpr auto make_tuple_of_vectors()
{
    return identity<
        std::tuple< add_vector<Types>::type... >
    >{};
}

//
// Our matrix, it receives types of all its
// columns as template parameters
//
template<typename... ColumnTypes>
class matrix
{
    using matrix_internal_t = decltype(
        make_tuple_of_vectors<ColumnTypes...>
    )::type;

    static constexpr size_t columns_count = 
        sizeof...( Types );

public:
    // Don't know why you need a pointer here
    // It's better to store a value maybe
    matrix_internal_t* matrix_ptr;
};

Это решение позволяет хранить разные типы в разных столбцах. Проблема только с индексацией. Вы должны знать во время компиляции индекс столбца, к которому вы хотите получить доступ.

Вы можете предоставить следующую функцию-член:

template<size_t column_index>
auto get_column()
{
    static_assert(
        column_index < columns_count,
        "Out of range"
    );

    return std::get<column_index>( *matrix_ptr );
}

В каждом столбце, полученном с помощью следующего метода, который вы можете использовать [] operator.

Использование:

matrix<int, float, double> m;

// Get the first column (with integers)
auto v1 = m.get_column<0>();

// Get the second column (with floats)
auto v2 = m.get_column<1>();

// Get 4'th column, that doesn't exist
// Raises compilation error
// auto v4 = m.get_column<3>();

Чтобы получить доступ к ij'th элементу более элегантно, вы можете определить макрос:

// j must be known at compile-time
#define get_element( matrix, i, j ) matrix.get_column<j>()[i]

Для итерации над столбцами вы можете написать собственный for_each, но немного сложнее: попробуйте найти реализацию for_aech для кортежа или напишите ее самостоятельно :) Написание такого алгоритма - хорошая практика

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...