简体   繁体   English

具有显式构造函数的类是否需要emplace中的piecewise_construct?

[英]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::mapmapped_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::emplaceexplicit的文档并没有真正为我澄清这一点。

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可隐式转换为T1V可隐式转换为T2

 template<class U, class V> constexpr pair(U&& x, V&& y); 

Requires: is_constructible<first_type, U&&>::value is true and is_constructible<second_type, V&&>::value is true . 要求: is_constructible<first_type, U&&>::valuetrueis_constructible<second_type, V&&>::valuetrue

Effects: The constructor initializes first with std::forward<U>(x) and second with std::forward<V>(y) . 效果:构造函数first使用std::forward<U>(x)初始化, second使用std::forward<V>(y)初始化。

Remarks: If U is not implicitly convertible to first_type or V is not implicitly convertible to second_type this constructor shall not participate in overload resolution. 备注:如果U不能隐式转换为first_typeV不能隐式转换为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.

相关问题 为什么我需要在 map::emplace 中为不可复制对象的单个 arg 构造函数使用piecewise_construct? - why do i need to use piecewise_construct in map::emplace for single arg constructors of noncopyable objects? 为什么我们在 C++20 中需要 map emplace 中的分段构造? - Why do we need piecewise_construct in map emplace in C++20? 用于boost :: container :: map :: emplace()的piecewise_construct在哪里? - Where is piecewise_construct for boost::container::map::emplace()? 为什么unordered_map的pieceplace_construct参数的位置需要默认构造函数? - Why does unordered_map's emplace with piecewise_construct argument needs default constructor? 如何制作自己的piecewise_construct构造函数? - How can I make my own piecewise_construct constructor? std :: piecewise_construct语法如何工作? - How does the std::piecewise_construct syntax work? std :: piecewise_construct不会导致ODR违规吗? - Doesn't std::piecewise_construct cause a ODR violation? 显式和非显式构造函数 - Explicit and non-explicit constructors emplace_back和move分配构造函数存在问题 - Problems with emplace_back and move assignment constructors 显式构造函数中的类型推断 - Type inference in explicit constructors
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM