标签: initializer-list

如果copy-list-initialization允许显式构造函数会出现什么问题?

在C++标准§13.3.1.7[over.match.list]中,陈述如下:

在copy-list-initialization中,如果explicit选择了构造函数,则初始化是错误的.

这就是为什么我们不能这样做的原因,例如:

struct foo {
    // explicit because it can be called with one argument
    explicit foo(std::string s, int x = 0);
private:
    // ...
};

void f(foo x);

f({ "answer", 42 });
Run Code Online (Sandbox Code Playgroud)

(注意,这里发生的不是转换,即使构造函数是"隐式的"也不会是一个.这是一个foo对象直接使用它的构造函数初始化.除此之外std::string,这里没有转换.)

这对我来说似乎完全没问题.隐式转换不会让我感到困惑.

如果{ "answer", 42 }可以初始化其他东西,编译器不会背叛我并做错事:

struct bar {
    // explicit because it can be called with one argument
    explicit bar(std::string s, int x = 0);
private:
    // ...
};

void f(foo x);
void f(bar x); …
Run Code Online (Sandbox Code Playgroud)

c++ explicit-constructor initializer-list c++11

38
推荐指数
1
解决办法
3926
查看次数

std :: initializer_list作为函数参数

出于某种原因,我认为C++ 0x允许std::initializer_list作为函数的函数参数,例如,期望可以从这样构造的类型std::vector.但显然,它不起作用.这只是我的编译器,还是永远不会起作用?是因为潜在的重载解决问题吗?

#include <string>
#include <vector>

void function(std::vector<std::string> vec)
{
}

int main()
{
    // ok
    std::vector<std::string> vec {"hello", "world", "test"};

    // error: could not convert '{"hello", "world", "test"}' to 'std::vector...'
    function( {"hello", "world", "test"} );
}
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list c++11

35
推荐指数
1
解决办法
2万
查看次数

为什么`std :: initializer_list`没有提供下标运算符?

假设您正在编写一个接受被std::initializer_list调用list的函数,并且该函数需要随机访问其list元素.写list[i]代替是方便的list.begin()[i].那么为什么不std::initializer_list提供定义operator[]呢?

我想不出任何operator[]返回const T&不明确的情况.效率在这里似乎不是问题,因为std::initializer_list<T>::iterator别名const T*,显然是随机访问迭代器.

c++ iterator operator-overloading initializer-list c++11

35
推荐指数
2
解决办法
8163
查看次数

initializer_list和模板类型推导

考虑功能:

template<typename T>
void printme(T&& t) {
  for (auto i : t)
    std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)

或任何其他期望一个参数具有begin()/ end()启用类型的函数.

以下为什么违法?

printme({'a', 'b', 'c'});

当所有这些都合法时:

printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)

我们甚至可以这样写:

const auto il = {'a', 'b', 'c'};
printme(il);
Run Code Online (Sandbox Code Playgroud)

要么

printme<std::initializer_list<char>>({'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)

c++ templates initializer-list c++11

34
推荐指数
3
解决办法
7447
查看次数

为什么我不能使用统一初始化初始化初始化列表中的引用?

也就是说,为什么这样:

struct S {};

struct T
{
    T(S& s) : s{s} {}

    S& s;
};

int main()
{
    S s;
    T t{s};
}
Run Code Online (Sandbox Code Playgroud)

给我一个GCC 4.7的编译器错误:

test.cpp: In constructor 'T::T(S&)':
test.cpp:5:18: error: invalid initialization of non-const reference of type 'S&' from an rvalue of type '<brace-enclosed initializer list>'
Run Code Online (Sandbox Code Playgroud)

要修复错误,我必须更改s{s}s(s).这不会打破统一初始化的统一性吗?

编辑:我试过clang,clang接受它,所以也许这是一个GCC错误?

c++ reference initializer-list uniform-initialization c++11

33
推荐指数
3
解决办法
5010
查看次数

lambda返回initializer_list中的奇怪值

考虑一下这个C++ 11代码片段:

#include <iostream>
#include <set>
#include <stdexcept>
#include <initializer_list>


int main(int argc, char ** argv)
{
    enum Switch {
        Switch_1,
        Switch_2,
        Switch_3,
        Switch_XXXX,
    };

    int foo_1 = 1;
    int foo_2 = 2;
    int foo_3 = 3;
    int foo_4 = 4;
    int foo_5 = 5;
    int foo_6 = 6;
    int foo_7 = 7;

    auto get_foos = [=] (Switch ss) -> std::initializer_list<int> {
        switch (ss) {
            case Switch_1:
                return {foo_1, foo_2, foo_3};
            case Switch_2:
                return {foo_4, foo_5};
            case Switch_3: …
Run Code Online (Sandbox Code Playgroud)

c++ lambda initializer-list c++11

33
推荐指数
2
解决办法
2792
查看次数

initializer_list :: size()上的static_assert

为什么st_ :: initializer_list <_E> :: size在static_assert中是不允许的,即使它在我的libstdc ++(v.4.6)中被声明为constexpr?

例如,以下代码:

template<class T, int Length>
class Point
{
  public:
    Point(std::initializer_list<T> init)
    {
      static_assert(init.size() == Length, "Wrong number of dimensions");
    }
};

int main()
{
  Point<int, 3> q({1,2,3});

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

test.C: In constructor ‘Point<T, Length>::Point(std::initializer_list<_Tp>) [with T = int, int Length = 3]’:
test.C:60:26:   instantiated from here
test.C:54:7: error: non-constant condition for static assertion
test.C:54:73:   in constexpr expansion of ‘init.std::initializer_list<_E>::size [with _E = int, std::initializer_list<_E>::size_type = long unsigned int]()’
test.C:54:7: error: ‘init’ …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list constexpr c++11

31
推荐指数
3
解决办法
9640
查看次数

什么是Curly-Brace附上列表如果不是intializer_list?

我在这里问了一个问题:涉及非功能代码的initializer_list返回的生命周期扩展:

const auto foo = [](const auto& a, const auto& b, const auto& c) { return {a, b, c}; };
Run Code Online (Sandbox Code Playgroud)

我相信lambda试图回归intializer_list(这很糟糕,不要这样做.)但我得到了一个评论:

它不是一个initializer_list,它是一个初始化列表.两件不同的事情.

我只是认为,无论何时你做了一个花括号列表,你都在创建一个intializer_list.如果那不是正在发生的事情,花括号中的列表是什么?

c++ initialization initializer curly-braces initializer-list

31
推荐指数
3
解决办法
1349
查看次数

为什么在初始化列表可用时使用可变参数?

我一直想知道可变参数比初始化列表有什么优点.两者都提供相同的能力 - 将无限数量的参数传递给函数.

我个人认为初始化列表更优雅一些.语法不那么尴尬.

此外,随着参数数量的增加,初始化程序列表似乎具有明显更好的性能.

所以除了在C中使用可变参数的可能性之外我还缺少什么?

c++ performance variadic-functions initializer-list c++11

30
推荐指数
1
解决办法
1万
查看次数

使用支撑初始化列表时,为什么首选std :: initializer_list构造函数?

考虑一下代码

#include <iostream>

class Foo
{
    int val_;
public:
    Foo(std::initializer_list<Foo> il)
    {
        std::cout << "initializer_list ctor" << std::endl;
    }
    /* explicit */ Foo(int val): val_(val)
    {
        std::cout << "ctor" << std::endl;
    };
};

int main(int argc, char const *argv[])
{
    // why is the initializer_list ctor invoked?
    Foo foo {10}; 
}
Run Code Online (Sandbox Code Playgroud)

输出是

ctor
initializer_list ctor
Run Code Online (Sandbox Code Playgroud)

据我所知,该值10被隐式转换为Foo(第一个ctor输出),然后初始化构造函数启动(第二个initializer_list ctor输出).我的问题是为什么会发生这种情况?标准构造函数Foo(int)不是更好的匹配吗?也就是说,我本来希望这个片段的输出是公正的ctor.

PS:如果我将构造函数标记Foo(int)explicit,则Foo(int)调用唯一的构造函数,因为整数10现在不能隐式转换为a Foo.

c++ constructor initializer-list language-lawyer c++11

30
推荐指数
3
解决办法
2711
查看次数