std::initializer_list内置核心语言?在我看来,它是C++ 11的一个非常重要的特性,但它没有自己的保留关键字(或类似的东西).
相反,initializer_list它只是来自标准库的模板类,它具有来自编译器处理的新braced-init-list语法的特殊隐式映射. {...}
起初认为,这个解决方案非常黑客.
这是现在实现C++语言新增功能的方式:通过某些模板类的隐式角色而不是核心语言?
请考虑以下示例:
widget<int> w = {1,2,3}; //this is how we want to use a class
Run Code Online (Sandbox Code Playgroud)
为什么选择了新课程:
widget( std::initializer_list<T> init )
Run Code Online (Sandbox Code Playgroud)
而不是使用类似于以下任何想法的东西:
widget( T[] init, int length ) // (1)
widget( T... init ) // (2)
widget( std::vector<T> init ) // (3)
Run Code Online (Sandbox Code Playgroud)
const这里和那里添加const和&所有这些都已经成为语言的一部分.我只写了我的第一个想法,我相信还有很多其他方法.
class C
{
public:
C() : arr({1,2,3}) //doesn't compile
{}
/*
C() : arr{1,2,3} //doesn't compile either
{}
*/
private:
int arr[3];
};
Run Code Online (Sandbox Code Playgroud)
我相信原因是数组只能用=语法初始化,即:
int arr[3] = {1,3,4};
Run Code Online (Sandbox Code Playgroud)
PS请不要提及矢量,boost ::数组,以及它们对数组的优越性,我很清楚.
c++ initializer-list ctor-initializer aggregate-initialization c++11
在C++ 11中,我们有了用于初始化类的新语法,它为我们提供了如何初始化变量的大量可能性.
{ // Example 1
int b(1);
int a{1};
int c = 1;
int d = {1};
}
{ // Example 2
std::complex<double> b(3,4);
std::complex<double> a{3,4};
std::complex<double> c = {3,4};
auto d = std::complex<double>(3,4);
auto e = std::complex<double>{3,4};
}
{ // Example 3
std::string a(3,'x');
std::string b{3,'x'}; // oops
}
{ // Example 4
std::function<int(int,int)> a(std::plus<int>());
std::function<int(int,int)> b{std::plus<int>()};
}
{ // Example 5
std::unique_ptr<int> a(new int(5));
std::unique_ptr<int> b{new int(5)};
}
{ // Example 6
std::locale::global(std::locale("")); // copied from 22.4.8.3 …Run Code Online (Sandbox Code Playgroud) 如果我通过我的GCC 4.7快照传递以下代码,它会尝试将unique_ptrs 复制到向量中.
#include <vector>
#include <memory>
int main() {
using move_only = std::unique_ptr<int>;
std::vector<move_only> v { move_only(), move_only(), move_only() };
}
Run Code Online (Sandbox Code Playgroud)
显然,因为std::unique_ptr不可复制而无法工作:
错误:使用已删除的函数'std :: unique_ptr <_Tp,_Dp> :: unique_ptr(const std :: unique_ptr <_Tp,_Dp>&)[with _Tp = int; _Dp = std :: default_delete; std :: unique_ptr <_Tp,_Dp> = std :: unique_ptr]'
GCC是否正确尝试从初始化列表中复制指针?
我允许将元素移出std::initializer_list<T>?
#include <initializer_list>
#include <utility>
template<typename T>
void foo(std::initializer_list<T> list)
{
for (auto it = list.begin(); it != list.end(); ++it)
{
bar(std::move(*it)); // kosher?
}
}
Run Code Online (Sandbox Code Playgroud)
由于std::intializer_list<T>需要特殊的编译器注意并且没有像C++标准库的普通容器那样的值语义,所以我宁愿安全而不是抱歉并且问.
为什么我使用以下代码收到错误"可能无法初始化可变大小的对象"?
int boardAux[length][length] = {{0}};
Run Code Online (Sandbox Code Playgroud) 如果它甚至存在,std::map扩展的初始化列表会是什么样的?
我已经尝试了一些组合......好吧,我能用GCC 4.4想到的一切,但没有发现任何编译.
我找到了一个不起眼的日志记录错误,事实上长度为2的初始化列表似乎是一个特例!这怎么可能?
代码是使用Apple LLVM版本5.1(clang-503.0.40)编译的CXXFLAGS=-std=c++11 -stdlib=libc++.
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
typedef vector<string> Strings;
void print(string const& s) {
printf(s.c_str());
printf("\n");
}
void print(Strings const& ss, string const& name) {
print("Test " + name);
print("Number of strings: " + to_string(ss.size()));
for (auto& s: ss) {
auto t = "length = " + to_string(s.size()) + ": " + s;
print(t);
}
print("\n");
}
void test() {
Strings a{{"hello"}}; print(a, "a");
Strings b{{"hello", "there"}}; print(b, "b");
Strings c{{"hello", …Run Code Online (Sandbox Code Playgroud) 使用C++ 14标准,std::array可以使用单个括号进行初始化(请参阅http://en.cppreference.com/w/cpp/container/array):
然而,这并没有为工作std::array的std::pair.
为什么这些工作:
std::pair<int, int> p { 1, 2 };
std::array<int, 3> a {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
但是这不工作:
std::array<std::pair<int, int>, 3> b {{1, 11}, {2, 22}, {3, 33}};
Run Code Online (Sandbox Code Playgroud)
虽然这确实有效吗?
std::array<std::pair<int, int>, 3> b {{{1, 11}, {2, 22}, {3, 33}}};
Run Code Online (Sandbox Code Playgroud)
此外,为了完成,一个好的旧数组的初始化确实适用于单个大括号
std::pair<int, int> c[3] {{1, 11}, {2, 22}, {3, 33}};
Run Code Online (Sandbox Code Playgroud) 为什么doSomething编译器会先调用前两个,但是在列表中使用两个元素会导致调用不明确?
#include <vector>
#include <string>
void doSomething(const std::vector<std::string>& data) {}
void doSomething(const std::vector<int>& data) {}
int main(int argc, char *argv[])
{
doSomething({"hello"}); // OK
doSomething({"hello", "stack", "overflow"}); // OK
doSomething({"hello", "stack"}); // C2668 'doSomething': ambiguous call
return 0;
}
Run Code Online (Sandbox Code Playgroud) initializer-list ×10
c++ ×9
c++11 ×7
ambiguous ×1
c ×1
c++14 ×1
dictionary ×1
std ×1
templates ×1