Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么';t emplace_back()是否使用统一初始化?_C++_Vector_C++11_Uniform Initialization - Fatal编程技术网

C++ 为什么';t emplace_back()是否使用统一初始化?

C++ 为什么';t emplace_back()是否使用统一初始化?,c++,vector,c++11,uniform-initialization,C++,Vector,C++11,Uniform Initialization,以下代码: #include <vector> struct S { int x, y; }; int main() { std::vector<S> v; v.emplace_back(0, 0); } #包括 结构 { int x,y; }; int main() { std::向量v; v、 后侵位(0,0); } 使用GCC编译时给出以下错误: In file included from c++/4.7.0/i686-pc-linu

以下代码:

#include <vector>

struct S
{
    int x, y;
};

int main()
{
    std::vector<S> v;
    v.emplace_back(0, 0);
}
#包括
结构
{
int x,y;
};
int main()
{
std::向量v;
v、 后侵位(0,0);
}
使用GCC编译时给出以下错误:

In file included from c++/4.7.0/i686-pc-linux-gnu/bits/c++allocator.h:34:0,
                 from c++/4.7.0/bits/allocator.h:48,
                 from c++/4.7.0/vector:62,
                 from test.cpp:1:
c++/4.7.0/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = S; _Args = {int, int}; _Tp = S]':
c++/4.7.0/bits/alloc_traits.h:265:4:   required from 'static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = S; _Args = {int, int}; _Alloc = std::allocator<S>; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]'
c++/4.7.0/bits/alloc_traits.h:402:4:   required from 'static void std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = S; _Args = {int, int}; _Alloc = std::allocator<S>]'
c++/4.7.0/bits/vector.tcc:97:6:   required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int, int}; _Tp = S; _Alloc = std::allocator<S>]'
test.cpp:11:24:   required from here
c++/4.7.0/ext/new_allocator.h:110:4: error: new initializer expression list treated as compound expression [-fpermissive]
c++/4.7.0/ext/new_allocator.h:110:4: error: no matching function for call to 'S::S(int)'
c++/4.7.0/ext/new_allocator.h:110:4: note: candidates are:
test.cpp:3:8: note: S::S()
test.cpp:3:8: note:   candidate expects 0 arguments, 1 provided
test.cpp:3:8: note: constexpr S::S(const S&)
test.cpp:3:8: note:   no known conversion for argument 1 from 'int' to 'const S&'
test.cpp:3:8: note: constexpr S::S(S&&)
test.cpp:3:8: note:   no known conversion for argument 1 from 'int' to 'S&&'
在c++/4.7.0/i686 pc linux gnu/bits/c++分配器中包含的文件中。h:34:0,
从c++/4.7.0/bits/allocator.h:48,
从c++/4.7.0/vector:62,
来自测试。cpp:1:
c++/4.7.0/ext/new_allocator.h:在'void u gnu cxx::new_allocator::construct(_Up*,_Args&&&…)[with _Up=S;_Args={int,int};_Tp=S]的实例化中:
c++/4.7.0/bits/alloc_traits.h:265:4:static typename std::enable_if::type std::allocator_traits::_S_构造(_alloc&,_Tp*,_Args&……[with _Tp=S;_Args={int,int};_alloc=std::allocator;typename::enable_if::type=void])
c++/4.7.0/bits/alloc_traits.h:402:4:static void std::allocator_traits::construct(_-alloc&,_-Tp*,_-Args&&…[with _-Tp=S;_-Args={int,int};_-alloc=std::allocator]中的必填项
c++/4.7.0/bits/vector.tcc:97:6:void std::vector::emplace_back(_Args&&…[with _Args={int,int};_Tp=S;_Alloc=std::allocator]中的必填项
测试。cpp:11:24:从这里开始需要
c++/4.7.0/ext/new_allocator.h:110:4:错误:新初始值设定项表达式列表被视为复合表达式[-fppermissive]
c++/4.7.0/ext/new_allocator.h:110:4:错误:调用“S::S(int)”时没有匹配的函数
c++/4.7.0/ext/new_allocator.h:110:4:注意:候选对象是:
test.cpp:3:8:note:S::S()
test.cpp:3:8:注意:候选者需要0个参数,提供1个
test.cpp:3:8:note:constexpr S::S(const S&)
test.cpp:3:8:注意:参数1从'int'到'const S&'没有已知的转换
test.cpp:3:8:note:constexpr S::S(S&&)
test.cpp:3:8:注意:参数1没有从'int'到'S&&'的已知转换
建议
vector
使用常规的
()
构造函数语法从
emplace\u back()的参数构造元素。为什么
vector
不使用
{}
统一的初始化语法来制作上述示例

在我看来,使用
{}
(有构造函数时调用构造函数,但没有构造函数时仍能工作),使用
{}
,更符合C++11的精神——毕竟,统一初始化的全部要点是统一使用它——也就是说,到处都是——初始化对象。

伟大的思想都是一样的;v) 。我提交了一份缺陷报告,并建议对该主题的标准进行修改

另外,吕克·丹顿帮助我理解了困难

当炮位可建造时(23.2.1 [container.requirements.general]/13)需求用于初始化 如果是对象,则会发生直接初始化。初始化聚合或 将std::initializer\u list构造函数与emplace一起使用需要命名 初始化的类型并移动一个临时文件。这是由于 std::allocator::使用直接初始化构造,而不是 列表初始化(有时称为“统一初始化”) 语法

更改std::allocator::construct以使用列表初始化 除其他外,会优先考虑std::initializer\u list吗 构造函数重载,在非直观和 不可更改的方式-emplace_无法返回以访问 构造函数被std::initializer_list抢占 重新实现推回

std::vector<std::vector<int>> v;
v.emplace_back(3, 4); // v[0] == {4, 4, 4}, not {3, 4} as in list-initialization
std::vector v;
v、 后置(3,4);//v[0]={4,4,4},而不是列表初始化中的{3,4}
建议的折衷方案是将SFINAE与std::is_可构造一起使用, 它测试直接初始化是否格式正确。如果 is_constructable如果为false,则为另一个选项 选择std::allocator::construct重载,该重载使用 列表初始化。因为列表初始化总是依赖于 直接初始化时,用户将看到诊断消息,就像 始终使用列表初始化(统一初始化), 因为直接初始化重载不能失败

我可以看到两个角落的案例,暴露了这个方案中的漏洞。一个发生 当std::initializer\u列表的参数满足 构造函数,例如尝试在 上面的例子。解决方法是显式指定 std::初始值设定项\列表类型,如中所示 v、 放回(std::初始值设定项列表(3,4))。因为这和 语义就好像std::initializer_list被推导出来一样,似乎有 这里没什么问题

另一种情况是用于聚合初始化的参数 满足构造函数。因为聚合不能具有用户定义的 构造函数,这要求 聚合类型不能从聚合类型隐式转换,并且 初始值设定项列表有一个元素。解决办法是 为第二个成员提供初始值设定项。仍然不可能做到这一点 就地构造仅包含一个非静态数据成员的聚合 从可转换类型到聚合自身类型的转换。这 看起来是个可以接受的小洞


人们可以发明一种语言支持类型,在init列表中完美地转发语法大括号。然后你可以说emplace_back({a,b,…})@johanneschaub litb:IMHO,这更像是
std::initializer_list
应该是什么。但是对
std::allocator
的简单修改应该可以解决问题。@johanneschaub litb安放的优势在于创建不可移动的对象。为什么能够放置集装箱很重要?同样,请记住,
initializer\u list
也是不可移动的,并且总是制作一份副本