提问人:QuaternionsRock 提问时间:9/9/2021 最后编辑:Vlad from MoscowQuaternionsRock 更新时间:9/9/2021 访问量:68
参数类型为“const T &”和类型为“const T<U> &”的复制构造函数之间是否有区别?
Is there a difference between a copy constructor with an argument type of `const T &` and of type `const T<U> &`?
问:
从 C++ 11 开始,定义了三个构造函数,这些构造函数大致等同于以下类中的构造函数:std::allocator
template<typename T>
class allocator {
public:
constexpr allocator() noexcept = default;
constexpr allocator(const allocator &other) noexcept = default;
template<typename U>
constexpr allocator(const allocator<U> &other) noexcept {};
};
第一个是默认构造函数,第二个是复制构造函数 - 非常标准的东西。但是,第三个构造函数让我很困惑。从技术上讲,它似乎是复制构造函数的专用化?如果是这样的话,第二个构造函数甚至会被调用吗?是必需的吗?编译器如何知道为第三个构造函数提供默认实现?= default
答:
2赞
Vlad from Moscow
9/9/2021
#1
This template 构造函数
template<typename U>
constexpr allocator(const allocator<U> &other) noexcept {};
不是复制构造函数。
Copy 构造函数是类的非模板成员函数。
当等于 false 时,将选择此模板构造函数。std::is_same_v<T, U>
2赞
Remy Lebeau
9/9/2021
#2
从技术上讲,它 [第三个构造函数] 似乎是复制构造函数的专用化?
它根本不是复制构造函数。它实际上是一个转换构造函数。
第二个构造函数甚至会被调用吗?
如果一个对象用于构造另一个对象,则将使用第二个构造函数,是的。例如:allocator<T>
allocator<T>
allocator<int> a1;
allocator<int> a2(a1);
但是,如果使用不同的对象来构造对象,其中 与 的类型不同,则将使用第三个构造函数。例如:allocator<U>
allocator<T>
U
T
allocator<short> a1;
allocator<int> a2(a1);
是必需的吗?
= default
仅当希望编译器自动生成实现时。否则,您必须自己提供一个。
编译器如何知道为第三个构造函数提供默认实现?
构造函数主体中的所有内容都是用户定义的。如果没有,则需要改用(或)。{}
{}
= default
= delete
在未删除的构造函数中,编译器始终默认初始化每个类成员,除非在构造函数的成员初始化列表中另有指定 - 第三个构造函数没有该列表。
评论
0赞
QuaternionsRock
9/9/2021
谢谢你。因此,我最近的理解是,需要第三个构造函数来允许从另一种类型的分配器进行转换,而它的主体恰好是空的,因为不需要任何初始化。另一方面,需要第二个构造函数来确保编译器也为 T 和 u 相同的情况创建一个(可能更有效?)复制构造函数。这是正确的吗?std::allocator
评论
allocator<T>
U
T
{}
= default
= delete
allocator
allocator<T>
= default
{}
std::allocator
{}
std::allocator
{}