C++ 如果模板化构造函数参数是从非模板化基类(Armadillo)派生的,则它们似乎并不关心其类型
我有以下两个类(人为的例子):C++ 如果模板化构造函数参数是从非模板化基类(Armadillo)派生的,则它们似乎并不关心其类型,c++,templates,constructor,armadillo,C++,Templates,Constructor,Armadillo,我有以下两个类(人为的例子): #包括 模板 A类:公共arma::vec3 { 公众: 使用arma::vec3::vec3; }; 模板 B类 { 公众: B(常数A&A){} }; 运行以下代码时: int main() { A<int> a; B<int> b_i { a }; // Should always pass. B<double> b_d { a }; // Should fail as templat
#包括
模板
A类:公共arma::vec3
{
公众:
使用arma::vec3::vec3;
};
模板
B类
{
公众:
B(常数A&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.
}
intmain()
{
A A;
B_i{a};//应该总是通过。
B_d{a};//应该失败,因为类和构造函数参数之间的模板类型不同。
}
我希望看到本页底部的错误,因为对象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) {}
};
#包括
模板
A类:公共arma::vec3
{};
模板
B类
{
公众:
B(常数A&A){}
};
我得到了预期的行为(编译时错误):
错误:调用'B::B()'时没有匹配的函数
BB_d{a};//应失败,因为类和构造函数参数之间的模板类型不同。
我不是模板专家,也不知道犰狳向量库的内部工作原理,但有人能想到为什么继承arma::vec3构造函数会破坏我的代码(不抛出错误)?感谢因为A
(对于任何T
)是vec3
(因为继承),并且您正在使用vec3
构造函数,根据该构造函数包含一个复制构造函数,A
对象将愉快地从任何vec3
对象复制构建
当您使用arma::vec3::vec3
将vec3
构造函数复制到A
类中而不进行修改时,它基本上创建了A(const vec3&)
构造函数,而不是A(const A&)
构造函数
当您没有使用
部分时,编译器自动生成的复制构造函数将是A
类可用的唯一复制构造函数,它将是A(const A&)
,因为A
(对于任何t
)是vec3
(由于继承),您正在使用的vec3
构造函数,根据它包含一个复制构造函数,a
对象将愉快地从任何vec3
对象复制构造
当您使用arma::vec3::vec3
将vec3
构造函数复制到A
类中而不进行修改时,它基本上创建了A(const vec3&)
构造函数,而不是A(const A&)
构造函数
当您没有使用
部分的时,编译器自动生成的复制构造函数将是A
类可用的唯一复制构造函数,它将是A(const A&)
谢谢您的帮助。但是,当我从B
中删除成员A\code>并使构造函数什么也不做时,我观察到了相同的模式:B(const A&A){}
。由于a
是通过(const)引用传递的,我看不到在哪里调用arma::vec3
copy构造函数,因为我看不到创建任何a
类型的对象。我对引用传递给构造函数的理解是否错误?还是这里发生了什么事?我对问题进行了编辑,以反映上述更改。感谢您的帮助。但是,当我从B
中删除成员A\code>并使构造函数什么也不做时,我观察到了相同的模式:B(const A&A){}
。由于a
是通过(const)引用传递的,我看不到在哪里调用arma::vec3
copy构造函数,因为我看不到创建任何a
类型的对象。我对引用传递给构造函数的理解是否错误?还是这里发生了什么事?我对问题进行了编辑,以反映上述变化。
#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.