template <typename T> struct A {
A(T);
A(const A&);
};
int main()
{
A x(42); // #1
A y = x; // #2
}
据我了解,#1 的 T
将使用隐式演绎指南进行演绎
从第一个 ctor 生成。然后 x
将使用该ctor初始化。
不过,对于 #2,T
将使用复制推导候选(据我了解,这是推导指南的一个特定情况)推导(然后是 y
将使用第二个 ctor 进行初始化)。
为什么不能使用从 copy-ctor 生成的(隐式)推导指南来推导 #2 的 T
?
我想我只是不明白复制扣除候选人的一般用途。
最佳答案
添加复制扣除的措辞的初稿是P0620R0 ,其中提到
This paper is intended to resolve
- The direction on wrapping vs. copying from EWG on Monday in Kona
关于那次 session 的一些笔记可在 https://botondballo.wordpress.com/2017/03/27/trip-report-c-standards-meeting-in-kona-february-2017/ :
Copying vs. wrapping behaviour. Suppose
a
is a variable of typetuple<int, int>
, and we writetuple b{a};
. Should the type ofb
betuple<int, int>
(the "copying" behaviour), ortuple<tuple<int, int>>
(the "wrapping" behaviour)? This question arises for any wrapper-like type (such aspair
,tuple
, oroptional
) which has both a copy constructor and a constructor that takes an object of the type being wrapped. EWG felt copying was the best default. There was some talk of making the behaviour dependent on the syntax of the initialization (e.g. the{ }
syntax should always wrap) but EWG felt introducing new inconsistencies between the behaviours of different initialization syntaxes would do more harm than good.
@kiloalphaindia explained this in a comment :
If #2 would use
A::A(T)
we would end up withy
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>>
}
关于c++ - 为什么需要复制扣除候选作为单独的扣除指南?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50292874/