[英]Do classes with explicit constructors require piecewise_construct in emplace?
If I create a struct with an explicit
constructor 如果我使用
explicit
构造函数创建结构
struct A {
int x;
explicit A(int x):x(x){};
};
And then use it as the mapped_type
in a std::map
, I am able to emplace with the piecewise constructor: 然后将其用作
std::map
的mapped_type
,我可以将其与分段构造函数一起使用:
#include <map>
std::map<int, A> foo;
foo.emplace(
std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(10)
);
But I when I try to use the move or template constructors, I get errors and can't compile: 但是,当我尝试使用move或template构造函数时,出现错误并且无法编译:
foo.emplace(std::make_pair(2, 20)); // <-- doesn't work
foo.emplace(3, 30); // <-- doesn't work
What's going on here? 这里发生了什么? Until now, I hadn't appreciated that there was much of a difference between these different usages.
直到现在,我还没有意识到这些不同用法之间有很大的不同。 I guess, with the pair move constructor, it could make sense that there's an implicit conversion from
std::pair<int, A>
... but why does that have to happen in the template constructor? 我猜想,使用pair move构造函数,从
std::pair<int, A>
进行隐式转换是有意义的,但是为什么必须在模板构造函数中发生这种转换? And then why not with the piecewise constructor?? 然后为什么不使用分段构造函数呢?
I've poked around a bit, but the docs for std::map::emplace
and for explicit
don't really clarify this for me. 我戳了一下,但是
std::map::emplace
和explicit
的文档并没有真正为我澄清这一点。
Before N4387 , pair<T1, T2>
's constructors taking U
/ V
do not exist unless U
is implicitly convertible to T1
and V
is implicitly convertible to T2
: 在N4387之前,
pair<T1, T2>
的使用U
/ V
的构造函数不存在,除非U
可隐式转换为T1
且V
可隐式转换为T2
:
template<class U, class V> constexpr pair(U&& x, V&& y);
Requires:
is_constructible<first_type, U&&>::value
istrue
andis_constructible<second_type, V&&>::value
istrue
.要求:
is_constructible<first_type, U&&>::value
为true
,is_constructible<second_type, V&&>::value
为true
。Effects: The constructor initializes
first
withstd::forward<U>(x)
andsecond
withstd::forward<V>(y)
.效果:构造函数
first
使用std::forward<U>(x)
初始化,second
使用std::forward<V>(y)
初始化。Remarks: If
U
is not implicitly convertible tofirst_type
orV
is not implicitly convertible tosecond_type
this constructor shall not participate in overload resolution.备注:如果
U
不能隐式转换为first_type
或V
不能隐式转换为second_type
此构造方法不得参与重载解析。
Likewise for the const pair<U, V>&
and pair<U, V>&&
constructor. 同样对于
const pair<U, V>&
和pair<U, V>&&
构造函数。
Since those constructors effectively don't exist, your later two emplace
s will not work. 由于这些构造函数实际上不存在,因此后面的两个
emplace
将无法工作。
N4387 changed the rules here so that instead those constructors become explicit
if both types are constructible from the corresponding argument type but at least one is not implicitly convertible from the argument type. N4387在此处更改了规则,因此,如果两种类型都可以从相应的参数类型构造而不能从参数类型隐式转换,则这些构造函数将变为
explicit
式。 In C++17, therefore, all three emplace
s will compile. 因此,在C ++ 17中,所有三个
emplace
都将编译。 Also, as the paper addresses a defect report raising pretty much this exact issue (among several), implementations may also choose to implement it in earlier standard modes. 另外,由于本文着眼于缺陷报告,提出了很多确切的问题 (在多个问题中),实现者也可以选择以较早的标准模式实现它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.