Аргументы шаблонного конструктора, похоже, не заботятся об их типе, если они получены из не шаблонного базового класса (Armadillo) - PullRequest
1 голос
/ 26 мая 2020

У меня есть следующие два класса (надуманный пример):

#include <armadillo>

template<typename T>
class A : public arma::vec3
{
public:

     using arma::vec3::vec3;
};

template<typename T>
class B
{
public:

    B(const A<T>& a) {}
};

При выполнении следующего кода:

int main()
{
    A<int> a;

    B<int> b_i { a };     // Should always pass.
    B<double> b_d { a };  // Should fail as template type is different between class and constructor argument.
}

Я бы ожидал ошибки в внизу этой страницы, потому что объект b_d имеет тип шаблона double, а тип шаблона в конструкторе B совпадает с шаблоном класса B, но Этот код проходит без каких-либо проблем, что неправильно.

Однако, если я удалю унаследованный конструктор (ы) arma :: vec3:

#include <armadillo>

template<typename T>
class A : public arma::vec3
{};

template<typename T>
class B
{
public:

    B(const A<T>& a) {}
};

, я получаю ожидаемое поведение (ошибка времени компиляции):

error: no matching function for call to ‘B<double>::B(<brace-enclosed initializer list>)’
 B< double > b_d { a };  // Should fail as template type is different between class and constructor argument.

Я не эксперт по шаблонам и не знаю, как устроена векторная библиотека броненосцев, но может ли кто-нибудь придумать причину, по которой наследование конструктора (ов) arma :: vec3 нарушает мой код ( не выкидывает ошибку)? Спасибо

1 Ответ

3 голосов
/ 26 мая 2020

Потому что A<T> (для любого T) - это vec3 (из-за наследования), а вы using конструкторы vec3, которые, согласно , документация включает copy-constructor, объект A<T> будет успешно сконструирован из любого vec3 объекта.

Когда вы выполняете using arma::vec3::vec3, вы копируете конструкторы vec3 в класс A<T> без модификаций, он в основном создает конструктор A(const vec3&), а не конструктор A(const A&).


Если у вас нет части using, то компиляторы автоматически сгенерированный конструктор копирования будет единственным конструктором копирования, доступным для класса A<T>, и это будет A(const A&).

...