除非我弄错了,否则应该可以通过以下方式创建一个std:array:
std::array<std::string, 2> strings = { "a", "b" };
std::array<std::string, 2> strings({ "a", "b" });
Run Code Online (Sandbox Code Playgroud)
然而,使用GCC 4.6.1我无法使其中任何一个工作.编译器简单地说:
expected primary-expression before ',' token
Run Code Online (Sandbox Code Playgroud)
然而初始化列表与std :: vector一起工作正常.那是哪个呢?我错误地认为std :: array应该接受初始化列表,还是让GNU标准C++库团队搞错了?
C++中的初始化列表构造函数经常会引起麻烦; 例如
using std::vector;
using std::string;
vector<string> v{3}; // vector of three empty strings
vector<int> u{3}; // vector of one element with value 3
Run Code Online (Sandbox Code Playgroud)
(只是为了澄清,我的意思是<int>
构造函数是一个初始化列表构造函数,而<string>
一个不是.)
该int
案例与初始化列表构造函数匹配,而string
案例则不匹配.这有点难看,常常会造成麻烦.在Scott Meyers的Effective Modern C++的早期章节(第7项)中也注意到了这一点,他将其描述为标准中有些令人不快的部分,每当初始化列表构造函数可用时,编译器将跳过箍尝试匹配它,优先于每个其他构造函数.
当然,int case可以通过改变u{3}
来轻松修复u(3)
,但这不是重点.
这是理想的行为吗?C++标准委员会是否有任何讨论或计划来解决这种模糊/不愉快?一个例子是要求初始化程序列表构造函数被调用,如下所示:vector<int> u({3})
这已经是合法的.
要std::array
使用某些值初始化a ,您需要使用以下方法:
std::array<int,3> an_array{{3,4,5}};
Run Code Online (Sandbox Code Playgroud)
我知道我们需要两个花括号的原因(一个用于std::array
内部,另一个用于内部c-style array
).
我的问题:为什么,按标准,std::array
不包含直接初始化内部的初始化列表构造函数c-style array
?初始化为不是更友好的眼睛:
std::array<int,3> an_array{3,4,5};
Run Code Online (Sandbox Code Playgroud)
编辑:
此信息来自http://en.cppreference.com/w/cpp/container/array.我以为我的编译器允许第二个版本直接作为非标准扩展.现在,我甚至不确定这个案例的标准是什么.
//构造使用聚合初始化
std::array<int, 3> a1{ {1, 2, 3} };
// C++ 11中需要的双括号(不是在C++ 14中)
我有一个问题,即在使用 VS2017(C++14、C++17 和 ISO 最新版本)时,我无法将某个构造函数与数组初始值设定项一起使用。
当它应该使用填充有单个元素的容器调用构造函数时,我收到C2397 conversion from 'double' to 'unsigned int' requires a narrowing conversion
错误。
#include <vector>
class obj
{
public:
obj(const std::vector<double>& values, unsigned int stride)
: values_(values), stride_(stride)
{
}
obj(unsigned int m, unsigned int n)
: stride_(n)
{
}
private:
unsigned int stride_;
std::vector<double> values_;
};
int main(int argc, char** argv)
{
obj m(1, 1); // correct constructor called.
obj mm({ 42.0 }, 1); // Error C2397
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我可以通过显式声明容器来解决这个问题......
obj mm(std::vector<double>({ 42.0 …
Run Code Online (Sandbox Code Playgroud) 以下代码在clang 3.6(C++ 14)上编译,但在GCC 5.3(C++ 14)上没有编译
#include <array>
#include <utility>
struct super: std::array<int, 3> {
using base = std::array<int, 3>;
template <typename... Ts>
super(Ts&&... xs)
: base{std::forward<Ts>(xs)...} {
// nop
}
};
int main() {
super obj(1, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)
产生的错误消息是
/tmp/gcc-explorer-compiler116029-73-105rz4g/example.cpp: In instantiation of 'super::super(Ts&& ...) [with Ts = {int, int, int}]':
15 : required from here
9 : error: array must be initialized with a brace-enclosed initializer
: base{std::forward<Ts>(xs)...} {
^
9 : error: too many initializers for 'std::array<int, …
Run Code Online (Sandbox Code Playgroud)