您可以使用初始化列表构建一个std :: array:
std::array<int, 3> a = {1, 2, 3}; // works fine
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试从std::initializer_list作为类中的数据成员或基础对象构造它时,它不起作用:
#include <array>
#include <initializer_list>
template <typename T, std::size_t size, typename EnumT>
struct enum_addressable_array : public std::array<T, size>
{
typedef std::array<T, size> base_t;
typedef typename base_t::reference reference;
typedef typename base_t::const_reference const_reference;
typedef typename base_t::size_type size_type;
enum_addressable_array(std::initializer_list<T> il) : base_t{il} {}
reference operator[](EnumT n)
{
return base_t::operator[](static_cast<size_type>(n));
}
const_reference operator[](EnumT n) const
{
return base_t::operator[](static_cast<size_type>(n));
}
};
enum class E {a, b, c};
enum_addressable_array<char, …Run Code Online (Sandbox Code Playgroud) 为什么这样做:
std::pair<int, int> p = {1,2};
std::vector<std::pair<int, int>> vp = { {1,2}, {3,4} };
Run Code Online (Sandbox Code Playgroud)
但这不是吗?
std::array<int, 2> a = {1,2}; // still ok
std::vector<std::array<int, 2>> va = { {1,2}, {3,4} };
Run Code Online (Sandbox Code Playgroud)
使用g ++ 4.5.1 -std=c++0x,第二行失败:
错误:无法转换
‘{{1, 2}, {3, 4}}’为‘std::vector<std::array<int, 2u> >’
谢谢
我们可以在C++ 11中以两种方式初始化变量
一:
int abc = 7;
Run Code Online (Sandbox Code Playgroud)
二:
int abc {7};
Run Code Online (Sandbox Code Playgroud)
这两种方法有什么区别?
编译器如何区别对待它们或执行这些代码的方式?
以下代码构建,编译和运行(C++,mingw)似乎没有任何问题.但是,我保证在函数的参数列表中使用初始化列表构造的对象仍然存在于该函数的范围内,即使该函数通过引用获取参数?
如果不是,在函数的参数列表(通过引用接受参数)中使用其初始化列表创建对象时可能是危险的,因为它会立即被破坏:在这种情况下,函数没有复制,但是对内存的引用可能会或可能不会被另一个进程重新分配?
struct S
{
S() : a(0), b(0) {}
S(int a, int b) : a(a), b(b) {}
int a;
int b;
};
void foo(const S& s)
{
std::cout << "s.a = " << s.a << std::endl;
std::cout << "s.b = " << s.b << std::endl;
}
int main()
{
foo({4,5}); // <-- What is the scope of the struct initialized here?
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我试着用gcc4.7编译以下代码片段
vector<pair<int,char> > vp = {{1,'a'},{2,'b'}};
//For pair vector, it works like a charm.
vector<tuple<int,double,char> > vt = {{1,0.1,'a'},{2,4.2,'b'}};
Run Code Online (Sandbox Code Playgroud)
但是,对于元组的向量,编译器抱怨:
错误:从初始化列表转换为'std :: tuple'将使用显式构造函数'constexpr std :: tuple <> :: tuple(_UElements && ...)[with _UElements = {int,double,char}; =无效 _Elements = {int,double,char}]'
编译器溢出的错误信息对我来说是完全乱码,我不知道元组的构造函数是如何实现的,但我知道它们完全可以使用统一初始化(如:)tuple<int,float,char>{1,2.2,'X'},因此,我想知道问题是否存在我遇到的只是编译器的TODO或它是由C++ 11标准定义的东西.
任何回复将不胜感激!
我试图用来std::make_unique实现一个构造函数要接收的类std::initializer_list.这是一个最小的案例:
#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
struct Foo {
Foo(std::initializer_list<std::string> strings) : strings(strings) {}
std::vector<std::string> strings;
};
int main(int, char**) {
auto ptr = std::make_unique<Foo>({"Hello", "World"});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以在Coliru上看到它没有构建:
main.cpp:14:56: error: no matching function for call to 'make_unique(<brace-enclosed initializer list>)'
auto ptr = std::make_unique<Foo>({"Hello", "World"});
Run Code Online (Sandbox Code Playgroud)
那么,make_unique据说无法使用initializer_lists?GCC 4.9.1中有错误吗?或者我忽略了什么?
GCC的实现破坏了std::initializer_list返回full-expression结束时从函数返回的数组.它是否正确?
此程序中的两个测试用例都显示在使用值之前执行的析构函数:
#include <initializer_list>
#include <iostream>
struct noisydt {
~noisydt() { std::cout << "destroyed\n"; }
};
void receive( std::initializer_list< noisydt > il ) {
std::cout << "received\n";
}
std::initializer_list< noisydt > send() {
return { {}, {}, {} };
}
int main() {
receive( send() );
std::initializer_list< noisydt > && il = send();
receive( il );
}
Run Code Online (Sandbox Code Playgroud)
我认为该计划应该有效.但潜在的标准有点令人费解.
return语句初始化一个返回值对象,就像它被声明一样
std::initializer_list< noisydt > ret = { {},{},{} };
Run Code Online (Sandbox Code Playgroud)
这initializer_list将从给定的初始化器系列初始化一个临时及其底层数组存储,然后initializer_list从第一个初始化器初始化另一个.阵列的寿命是多少?"数组的生命周期与initializer_list对象的生命周期相同." 但其中有两个; 哪一个是模棱两可的.8.5.4/6中的示例(如果它按照公布的方式工作)应该解决数组具有复制到对象的生命周期的歧义.然后返回值的数组也应该存在于调用函数中,并且应该可以通过将它绑定到命名引用来保留它.
对我而言,a pair只是a的特例tuple,但令我惊讶的是:
pair<int, int> p1(1, 2); // ok
tuple<int, int> t1(1, 2); // ok
pair<int, int> p2={1, 2}; // ok
tuple<int, int> t2={1, 2}; // compile error
Run Code Online (Sandbox Code Playgroud)
我们{}用来初始化时为什么会有区别tuple?
我试过甚至g++ -std=c++1y但仍然有错误:
a.cc: In function 'int main()':
a.cc:9:29: error: converting to 'std::tuple<int, int>' from initializer list would use explicit constructor 'constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = int; _U2 = int; <template-parameter-2-3> = void; _T1 = int; _T2 = int]'
tuple<int, int> t2={1, …Run Code Online (Sandbox Code Playgroud) 我最近遇到了初始化列表的一些问题.考虑一个存储类似地图数据的程序
struct MyMapLike {
MyMapLike(std::map<std::string, int> data)
:data(std::move(data))
{ }
private:
std::map<std::string, int> data;
};
Run Code Online (Sandbox Code Playgroud)
这看起来很直接.但是在初始化时,它会变得难看.我想让它看起来像
MyMapLike maps = { { "One", 1 }, { "Two", 2 } };
Run Code Online (Sandbox Code Playgroud)
但是编译器并不想接受这一点,因为上面意味着它应该寻找一个两个参数的构造函数,可以接受{ "One", 1 }和{ "Two", 2 }分别.我需要添加额外的大括号,使它看起来像一个单参数构造函数接受{ { ... }, { ... } }
MyMapLike maps = { { { "One", 1 }, { "Two", 2 } } };
Run Code Online (Sandbox Code Playgroud)
我不想那样写.由于我有类似map的类,并且初始化程序具有映射列表的抽象值,因此我想使用前一版本,并且独立于任何此类实现细节,例如构造函数的嵌套级别.
一个解决方法是声明一个初始化列表构造函数
struct MyMapLike {
MyMapLike(std::initializer_list<
std::map<std::string, int>::value_type
> vals)
:data(vals.begin(), vals.end())
{ }
MyMapLike(std::map<std::string, int> data) …Run Code Online (Sandbox Code Playgroud) 假设我想引用initializer_list我已定义的成员.我可以做吗?
这段代码在Visual Studio和gcc中编译并给出了预期的"13 55" ,我只想知道它是合法的:
const int foo[2] = {13, foo[0] + 42};
Run Code Online (Sandbox Code Playgroud) c++ arrays initializer-list language-lawyer aggregate-initialization
initializer-list ×10
c++ ×9
c++11 ×7
arrays ×3
tuples ×2
c++14 ×1
lifetime ×1
scope ×1
unique-ptr ×1