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

时间:2016-12-11 23:11:34

标签: c++ c++11 constructor

如果我使用start_time = models.TimeField() end_time = models.TimeField() def duration(self): return self.end_time - self.start_time 构造函数

创建结构
Public Sub GetQuote2()

Dim objXML           As Object
Dim strSymbol        As String
Dim strURL           As String
Dim strWFormat       As String

Set objXML = CreateObject("MSXML2.XMLHTTP")

strURL = "http://ca.finance.yahoo.com/d/quotes.csv?s="
strWFormat = "&f=sl1d1t1c1ohgv&e=.csv"

strSymbol = "MSFT"

objXML.Open "GET", strURL & strSymbol & strWFormat, False
objXML.Send

Debug.Print "Symbol = " & Split(objXML.ResponseText, ",")(0)
Debug.Print "Trade  = " & Split(objXML.ResponseText, ",")(1)
Debug.Print "Date   = " & Split(objXML.ResponseText, ",")(2)

End Sub

然后将其用作explicit中的struct A { int x; explicit A(int x):x(x){}; }; ,我可以使用分段构造函数进行处理:

mapped_type

但是当我尝试使用移动或模板构造函数时,我得到错误并且无法编译:

std::map

这里发生了什么?到目前为止,我还没有意识到这些不同用法之间存在很大差异。我想,使用对移动构造函数,可能有意义的是从#include <map> std::map<int, A> foo; foo.emplace( std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(10) ); 进行隐式转换...但为什么必须在模板构造函数中进行?然后为什么使用分段构造函数??

我已经戳了一下,但是foo.emplace(std::make_pair(2, 20)); // <-- doesn't work foo.emplace(3, 30); // <-- doesn't work std::pair<int, A>的文档并没有真正为我澄清这一点。

1 个答案:

答案 0 :(得分:3)

N4387之前,pair<T1, T2>的构造函数采用U / V do not exist,除非U可隐式转换为T1并且V可以隐式转换为T2

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

要求: is_constructible<first_type, U&&>::valuetrueis_constructible<second_type, V&&>::valuetrue

     

效果:构造函数使用first初始化std::forward<U>(x),使用second初始化std::forward<V>(y)

     

备注:如果U无法隐式转换为first_typeV,则无法隐式转换为second_type此构造函数   不参与重载决议。

同样适用于const pair<U, V>&pair<U, V>&&构造函数。

由于这些构造函数实际上不存在,因此后两个emplace将不起作用。

N4387在这里更改了规则,这样如果两个类型都可以从相应的参数类型构造,但是这些构造函数变为explicit,但至少有一个不能从参数类型隐式转换。因此,在C ++ 17中,所有三个emplace都将编译。此外,正如论文addresses a defect report raising pretty much this exact issue(在几个中),实现也可以选择在早期的标准模式中实现它。