led*_*ter 13 c++ templates template-argument-deduction argument-deduction c++17
template <typename T> struct A {
A(T);
A(const A&);
};
int main()
{
A x(42); // #1
A y = x; // #2
}
Run Code Online (Sandbox Code Playgroud)
据我了解,T
#1将使用第一个ctor生成的隐式演绎指南推导出.然后x
将使用该ctor初始化.
但是对于#2,T
将使用复制演绎候选人推断(根据我的理解,这是演绎指南的特定情况)(然后y
将使用第二个ctor初始化).
为什么不能T
使用复制版本生成的(隐含)演绎指南来推导#2?
我想我只是不明白复制演绎候选人的一般目的.
小智 12
添加复制扣除措辞的初稿是P0620R0,其中提到了这一点
本文旨在解决
- 星期一在科纳举行的EWG包装与复制的方向
有关该会议的一些说明,请访问 https://botondballo.wordpress.com/2017/03/27/trip-report-c-standards-meeting-in-kona-february-2017/:
复制与包装行为.假设
a
是一个类型的变量tuple<int, int>
,我们写tuple b{a};
.应该b
是tuple<int, int>
("复制"行为)的类型,还是tuple<tuple<int, int>>
("包装"行为)?这个问题出现了对任何包装样型(如pair
,tuple
或optional
),其具有两个拷贝构造函数和,是以类型的对象被包裹的构造函数.EWG认为复制是最好的默认.有一些关于使行为依赖于初始化语法的说法(例如{ }
语法应该总是换行),但是EWG认为在不同初始化语法的行为之间引入新的不一致会带来弊大于利.
如果#2将使用
A::A(T)
我们最终会与y
beeingA<A<int>>
.[...]
这是正确的.该A<A<int>>::A(A<int>)
构造函数的参数类型完全匹配.另一方面,你也是对的,A<int>::A(const A<int> &)
在这种情况下,这是首选.
但是考虑一下这个替代方案,其中函数等价显示A<A<int>>
如果不是复制演绎候选者则优先考虑:
template <typename T>
struct A {
A(T &&);
A(const A<T> &);
};
template <typename T> auto f(T &&) -> A<T>;
template <typename T> auto f(const A<T> &) -> A<T>;
int main() {
A x1(42); // A<int>
A y1 = std::move(x1); // A<int>
auto x2 = f(42); // A<int>
auto y2 = f(std::move(x2)); // A<A<int>>
}
Run Code Online (Sandbox Code Playgroud)