我想看看这个现有代码示例如何能够利用C++ 0x初始化列表功能.
Example0:
#include <vector>
#include <string>
struct Ask {
std::string prompt;
Ask(std::string a_prompt):prompt(a_prompt){}
};
struct AskString : public Ask{
int min;
int max;
AskString(std::string a_prompt, int a_min, int a_max):
Ask(a_prompt), min(a_min), max(a_max){}
};
int main()
{
std::vector<Ask*> ui;
ui.push_back(new AskString("Enter your name: ", 3, 25));
ui.push_back(new AskString("Enter your city: ", 2, 25));
ui.push_back(new Ask("Enter your age: "));
}
Run Code Online (Sandbox Code Playgroud)
它会支持这样的事情:
例1:
std::vector<Ask*> ui ={
AskString("Enter your name: ", 3, 25),
AskString("Enter your city: ", 2, 25),
Ask("Enter your age: ") …Run Code Online (Sandbox Code Playgroud) 唯一且非常不方便的警告std::array是,它不能从内置C数组的初始化列表中推断出它的大小,它的大小必须作为模板传递.
是否可以使用C++11initializer_list 实现类似std :: array的容器(内置C数组周围的薄包装器)?
我问,因为,与std :: array不同,它会自动从初始化列表中推断出数组的大小,这样更方便.例如:
// il_array is the hypothetical container
// automatically deduces its size from the initalizer list
il_array <int> myarr = {2, 4, 6, 7, 8};
Run Code Online (Sandbox Code Playgroud)
如果没有提供初始化列表,我们还希望提供一个构造函数来指定大小.例如:
// construct a fixed size array of size 10
il_array <int> myarr2 (10);
Run Code Online (Sandbox Code Playgroud)
这也将使容器与其他标准容器(例如vector,deque和list)更加一致.
据我所知,由于包裹的C数组(如T elems [size])必须具有恒定大小且initializer_list的size()成员函数不是常量,因此不可能.
另外,我想知道是否有可能使用可变参数模板来实现这样的容器,尽管从我读过的内容我不认为这是可能的.
我正在玩索引技巧,看看我可以去哪里,并遇到一个奇怪的错误...首先,简单的不那么老的指数:
template<std::size_t...>
struct indices {};
template<std::size_t N, std::size_t... Indices>
struct make_indices:
make_indices<N-1, N-1, Indices...>
{};
template<std::size_t... Indices>
struct make_indices<0, Indices...>:
indices<Indices...>
{};
Run Code Online (Sandbox Code Playgroud)
我创建了一个从a派生的编译时数组类std::initializer_list,并使其具有可索引性(假设N3471支持您的编译器.无论如何它将在下一个标准中).这里是:
template<typename T>
struct array:
public std::initializer_list<T>
{
constexpr array(std::initializer_list<T> values):
std::initializer_list<T>(values)
{}
constexpr auto operator[](std::size_t n)
-> T
{
return this->begin()[n];
}
};
Run Code Online (Sandbox Code Playgroud)
所以,我尝试创建一个函数,array在每个成员添加1后返回一个副本:
template<typename T, std::size_t... I>
auto constexpr add_one(const array<T>& a, indices<I...>)
-> const array<T>
{
return { (a[I]+1)... };
}
Run Code Online (Sandbox Code Playgroud)
并完成代码,这是我的主要:
int main()
{
constexpr array<int> a = …Run Code Online (Sandbox Code Playgroud) 我试图在编译时确定a std::initializer_list中的所有值是否唯一.我找到了一个解决方案,以确定列表的大小,但无法将其应用于内容.我已尝试使用自由函数和构造函数,但这两种方法都导致GCC 4.7.2出现以下错误.
错误:静态断言
错误的非常量条件:'begin'不是常量表达式
我意识到std::initializer_list没有声明成员,constexpr但我希望有一个像尺寸验证的解决方案.是否可以使用以下内容在编译时验证内容?
#include <initializer_list>
template<typename InputIterator>
constexpr bool Validate(InputIterator begin, InputIterator end)
{
static_assert(*begin == *end, "begin and end are the same");
// The actual implemetnation is a single line recursive check.
return true;
}
template<typename InputType>
constexpr bool Validate(const std::initializer_list<InputType>& input)
{
// "-1" removed to simplify and eliminate potential cause of error
return Validate(input.begin(), input.end() /* - 1 */);
}
int main()
{
Validate({1, 2, 1});
}
Run Code Online (Sandbox Code Playgroud) 我有一个vector<data>(data我自己的宠物类型),我想找到它的最大价值.
std::maxC++ 11中的标准函数似乎适用于对象集合,但它需要初始化列表作为其第一个参数,而不是像vector以下集合:
vector<data> vd;
std::max(vd); // Compilation error
std::max({vd[0], vd[1], vd[2]}); // Works, but not ok since I don't vd.size() at compile time
Run Code Online (Sandbox Code Playgroud)
我怎么解决这个问题?
在C++ 11中(引用N3337),std::begin()并std::end()指定为(§24.7[iterator.range]/p2-3)
Run Code Online (Sandbox Code Playgroud)template <class C> auto begin(C& c) -> decltype(c.begin()); template <class C> auto begin(const C& c) -> decltype(c.begin());2返回:
c.begin().Run Code Online (Sandbox Code Playgroud)template <class C> auto end(C& c) -> decltype(c.end()); template <class C> auto end(const C& c) -> decltype(c.end());3返回:
c.end().
std::initializer_list但是,为这些函数提供了自己的重载(第18.9.3节[support.initlist.range]):
Run Code Online (Sandbox Code Playgroud)template<class E> const E* begin(initializer_list<E> il) noexcept;1返回:
il.begin().Run Code Online (Sandbox Code Playgroud)template<class E> const E* end(initializer_list<E> il) noexcept;2返回:
il.end().
看起来这些重载除了基本模板之外没有做任何事情,除了(1)有noexcept规范和(2)按值取参数.但是,复制一个initializer_list没什么特别的(它只是复制一对指针或同样轻量级的东西),所以(2)没有创建行为上的差异.此外,begin()和end()许多标准集装箱的成员函数也是noexcept,但没有过载std::begin() …
最近我写了一个非常简单的课.
class C
{
public:
void AddString(std::initializer_list<std::pair<const char*,int>> x)
{
//irrelevant
}
};
int main()
{
C c;
c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
.... //other unimportant stuff
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令我惊喜的是,它编译并正常工作.有人可以向我解释一下编译器如何能够推断出嵌套的支撑初始化器是为了std::pair什么?我正在使用MSVS 2013.
c++ initializer-list c++11 list-initialization type-deduction
说我有这个结构:
struct position
{
int x, y;
};
Run Code Online (Sandbox Code Playgroud)
和另一个将其作为构造函数参数的类:
class positioned
{
public:
positioned(position p) : pos(p) {}
private:
position pos;
};
Run Code Online (Sandbox Code Playgroud)
我怎样才能搞定
auto bla = std::make_unique<positioned>({1,2});
Run Code Online (Sandbox Code Playgroud)
上班?
目前,编译器试图匹配initializer_list<int>并调用数组变量make_unique,这是愚蠢的,因为positioned只有一个构造函数.出现同样的问题emplace和emplace_back功能.几乎任何将其可变参数模板参数转发给类的构造函数的函数似乎都表现出这种行为.
我明白我可以解决这个问题
positioned一个两个int参数构造函数并将{}调用放入make_unique,或make_unique为position{1,2}.两者看起来都过于冗长,因为在我看来(在make_unique实现中付出了一些努力),这可以在没有参数类型的过度规范的情况下得到解决.
这是一个可解决的make_unique实施缺陷,还是一个无法解决,无趣的边缘案例,没有人应该关心?
作为一个更大项目的一部分,我正在玩std::tuple模板; 考虑以下代码:
template <typename ...T> void foo(tuple<T...> t) {}
void bar(tuple<int, char> t) {}
tuple<int, char> quxx() { return {1, 'S'}; }
int main(int argc, char const *argv[])
{
foo({1, 'S'}); // error
foo(make_tuple(1, 'S')); // ok
bar({1, 'S'}); // ok
quxx(); // ok
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据这个答案, C++ 17支持从复制列表初始化开始的元组初始化,但是由于我得到以下错误(GCC 7.2.0),所以似乎这种支持是有限的:
main.cpp: In function 'int main(int, const char**)':
main.cpp:14:17: error: could not convert '{1, 'S'}' from '<brace-enclosed initializer list>' to 'std::tuple<>'
foo({1, 'S'}); // error …Run Code Online (Sandbox Code Playgroud) c++ initializer-list variadic-templates uniform-initialization c++17
我问是因为auto推断{}是initializer_list。我不知道核心语言像这样依赖标准库中的任何其他类。你可以去掉vectoror array,C++ 仍然可以运行,但是去掉initializer_list它就会崩溃。
c++ ×10
initializer-list ×10
c++11 ×7
c++17 ×2
arrays ×1
c++14 ×1
compile-time ×1
constexpr ×1
std ×1
unique-ptr ×1
validation ×1