c++ - 初始化忽略构造函数模板

标签 c++ templates constructor initialization

在追查一些错误时,我偶然发现了以下初始化行为,这对我来说似乎很奇怪:虽然对现有构造函数进行初始化检查,但似乎存在忽略适合构造函数的模板的情况。例如考虑以下程序:

#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);

因为模板构造函数不被视为用户定义的复制构造函数,即复制构造函数必须是非模板。

隐式声明的复制构造函数在重载决议中比模板版本更匹配,并且是在复制构造 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&);
}

关于c++ - 初始化忽略构造函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115859/

相关文章:

c++ - 将具有公共(public)头文件的目标文件链接到 main 会给出体系结构 x86_64 错误的重复符号

java - 如何将cpp回调函数指针发送给java

javascript - 不同状态的 mustache 模板

c++ - 从模板文件生成代码

c# - 通过基类创建派生类的实例,无需硬编码

java - Java中如何使用父类抽象复制构造函数复制子类?

java - 在 Java 中运行构造函数代码之前是否初始化了字段?

c++ - make文件没有运行给出错误请帮助我

c++ - 类模板,在定义中引用它自己的类型

c++ - 一个只能由于整数溢出而失败的函数应该是 noexcept 吗?