在追查一些错误时,我偶然发现了以下初始化行为,这对我来说似乎很奇怪:在对现有构造函数进行初始化检查时,似乎存在忽略拟合构造函数的模板的情况。例如,考虑以下程序:
#include <iostream>
template<class T>
struct A {
A() {};
template<class S>
A(const A<S>& a) {std::cout << "constructor template used for A" << std::endl;};
};
template<class T>
struct B{
B() {};
B(const B<int>& b) {std::cout << "constructor used for B" << std::endl;};
};
int main() {
A<int> a;
B<int> b;
A<int> aa = a;
B<int> bb = b;
A<double> aaa = a;
}
对我来说,这会产生输出
constructor used for B
constructor template used for A
这意味着它不使用 main 第三行中的构造函数。为什么不?有理由吗?或者我的语法有问题吗?该模板似乎可以工作,因为它在最后一行中已成功使用。
我知道这个例子看起来过于复杂,但是各种简化使我想要显示的行为消失了。另外:初始化将使用模板专门化,这也是我目前防止这种情况导致错误的方法(它首先导致错误的地方)。
如果我的问题有任何问题,我很抱歉,我不是程序员,我不是母语人士,这是我的第一个问题,请原谅我。
编译器提供了一个隐式声明的非模板复制构造函数,其签名相当于
A(const A& a);
because模板构造函数不被视为用户定义的复制构造函数,即复制构造函数必须是非模板。
隐式声明的复制构造函数在重载决策中比模板版本更匹配,并且是在复制构造函数时被调用的构造函数。A<T>
从一个A<T>
。这可以用一个简单的例子来说明,其中用户定义了A(const A&)
:
#include <iostream>
template<class T>
struct A
{
A() {};
A(const A& a) {
std::cout << "copy constructor used for A" << std::endl;
}
template<class S>
A(const A<S>& a) {
std::cout << "constructor template used for A" << std::endl;
}
};
int main()
{
A<int> ai;
A<double> ad = ai; / calls template conversion contructor
A<int> ai2 = ai; // calls copy constructor A(const A&);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)