标签: list-initialization

带大括号的 std::vector init 调用复制构造函数两次

为什么当我用大括号初始化 std::vector 时

std::vector<TS> vec {ts1, ts2};
Run Code Online (Sandbox Code Playgroud)

编译器调用两次复制构造函数运算符?另一方面 - 使用push_back它只调用一次。

#include <iostream>
#include <vector>
using namespace std;

struct TS{
    TS(){
        cout<<"default constructor\n";
    }

    TS(const TS &other) {
        cout<<"Copy constructor\n";
    }

    TS(TS &&other) noexcept{
        cout<<"Move constructor\n";
    }

    TS& operator=(TS const& other)
    {
        cout<<"Copy assigment\n";
        return *this;
    }

    TS& operator=(TS const&& other) noexcept
    {
        cout<<"Move assigment\n";
        return *this;
    }

    ~TS(){
        cout<<"destructor\n";
    }

};

int main() {
    TS ts1;
    TS ts2;
    cout<<"-----------------------------------------\n";
    std::vector<TS> vec {ts1, ts2};
    //vec.push_back(ts1);
    //vec = {ts1, ts2};
    cout<<"-----------------------------------------\n";



    return …
Run Code Online (Sandbox Code Playgroud)

c++ curly-braces stdvector list-initialization

6
推荐指数
1
解决办法
1663
查看次数

列表初始化不能用于私有成员吗?

struct A
{
private:
    int a, b, c;
};

int main()
{
    A a1{};
    A a2 = {};

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

该代码由VC++ 2012编译(最新更新"2012年11月CTP").

我希望a1和a2是零初始化的,但不是.a1和a2未初始化.

为什么?

c++ c++11 list-initialization

5
推荐指数
2
解决办法
164
查看次数

如何初始化std :: array <std :: array <T,2>,2>的对象?

我正在尝试初始化类型的对象:

template<typename T>
  struct thing : std::array<std::array<T, 2>, 2>
  {
  };

thing<int> t1 {{ {1,2}, {3,4} }};
Run Code Online (Sandbox Code Playgroud)

我明白了:

 error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’
 thing<int> t1 {{{1,2},{3,4}}};
Run Code Online (Sandbox Code Playgroud)

同上

thing<int> t0{{ 1, 2, 3, 4 }};
Run Code Online (Sandbox Code Playgroud)

和其他几件事.

c++ initialization c++11 list-initialization

5
推荐指数
1
解决办法
237
查看次数

为什么braced-init-list在函数调用和构造函数调用中表现不同?

使用clang 3.5.0和gcc 4.9.1编译以下代码会在最后一个语句中产生错误.

#include <iostream>

struct Foo { Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; } };

void bar(int x, int y) { std::cout << "bar(int = " << x << ", int = " << y << ")" << std::endl; }

int main()
{
   Foo({}, {});   // Foo(int = 0, int = 0)
   Foo({1}, {2}); // Foo(int = 1, int = 2)
   Foo({1, …
Run Code Online (Sandbox Code Playgroud)

c++ constructor function list-initialization c++14

5
推荐指数
1
解决办法
131
查看次数

无法在初始化时转换Type

我想我错过了什么,我不知道到底是什么.我们来看看代码片段.

template <typename T>
struct Foo { 
    Foo (int n, int p, string s, T t = {})
    : m_n {n}, m_p {p}, m_s {s}, m_t {t}
    {}

    const int m_n;
    const int m_p;
    const string m_s;
    T m_t;
};
Run Code Online (Sandbox Code Playgroud)

用法如下:

Foo<int> f_int1 {1, 2, "A", 155};
Foo<int> f_int2 {1, 2, "A"};
Run Code Online (Sandbox Code Playgroud)

一切都像预期的那样.但是当我想将用户定义的类型作为Foo的T参数时,会发生一些错误.考虑:

struct Boo {
    int z;
    int l;
};
Run Code Online (Sandbox Code Playgroud)

用法:

Foo<Boo> f_boo1 {1, 2, "A"};
Foo<Boo> f_boo2 {1, 2, "A", {1, 2}};
Run Code Online (Sandbox Code Playgroud)

这两条指令都给出了(gcc 4.8.1):

cannot convert ‘Boo’ to …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 list-initialization

5
推荐指数
1
解决办法
5098
查看次数

复制列表初始化与临时列表初始化临时

给定以下结构:

struct ABC
{
    ABC(){cout << "ABC" << endl;}
    ~ABC() noexcept {cout << "~ABC" << endl;}
    ABC(ABC const&) {cout << "copy" << endl;}
    ABC(ABC&&) noexcept {cout << "move" << endl;}
    ABC& operator=(ABC const&){cout << "copy=" << endl;}
    ABC& operator=(ABC&&) noexcept {cout << "move=" << endl;}
};
Run Code Online (Sandbox Code Playgroud)

输出:

std::pair<std::string, ABC> myPair{{}, {}};
Run Code Online (Sandbox Code Playgroud)

是:

ABC
copy
~ABC
~ABC
Run Code Online (Sandbox Code Playgroud)

而输出:

std::pair<std::string, ABC> myPair{{}, ABC{}};
Run Code Online (Sandbox Code Playgroud)

是:

ABC
move
~ABC
~ABC
Run Code Online (Sandbox Code Playgroud)

在试图理解两者之间的差异时,我认为我已经确定第一种情况是使用复制列表初始化,而第二种情况使用未命名临时的直接列表初始化(数字7和2分别在这里) :http://en.cppreference.com/w/cpp/language/list_initialization).

搜索类似的问题我发现:为什么标准区分直接列表初始化和复制列表初始化?并且:复制列表初始化是否从概念上调用了复制ctor?.

这些问题的答案讨论了这样一个事实:对于复制列表初始化,使用显式构造函数会使代码格式错误.事实上,如果我将ABC的默认构造函数显式化,我的第一个例子将不会编译,但这可能是(可能)另一个问题.

所以,问题是:为什么临时复制在第一种情况下,但在第二种情况下移动?什么阻止它在复制列表初始化的情况下被移动?

作为注释,以下代码: …

move temporary-objects c++11 list-initialization

5
推荐指数
1
解决办法
574
查看次数

这实际上是不明确的吗?

所以我知道代码中的大括号不仅仅意味着initializer_list:如果不是intializer_list,那么什么是Curly-Brace封闭列表?

但他们应该默认什么?

例如,假设我定义了一个重载函数:

void foo(const initializer_list<int>& row_vector) { cout << size(row_vector) << "x1 - FIRST\n"; }
void foo(const initializer_list<initializer_list<int>>& matrix) { cout << size(matrix) << 'x' << size(*begin(matrix)) << " - SECOND\n"; }
Run Code Online (Sandbox Code Playgroud)

如果我打电话foo({ 1, 2, 3 })第一个显然会被调用.如果我打电话foo({ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } })第二人显然会被召唤.

但如果我打电话怎么办:

foo({ { 1 }, { 2 }, { 3 } })
Run Code Online (Sandbox Code Playgroud)

那些嵌套的括号 …

c++ nested initializer-list ambiguous list-initialization

5
推荐指数
1
解决办法
169
查看次数

模板变量C数组完全专业化应该指定数组大小吗?

我正在尝试实现具有以下特征的模板化C数组:

// template definition
template< int a, int b > constexpr int    arr[]       = { 1 };

// partial specialization, works ok
template< int b >        constexpr double arr<0, b>[] = { 2.0 };

// full specialization, compile error in MSVC, ok in g++
template< >              constexpr float  arr<1, 0>[] = { 3.0f };
Run Code Online (Sandbox Code Playgroud)

我将Visual Studio 2017和MSVC编译器与C ++标准设置为C ++ 17一起使用,并且编译器抱怨了C2133: 'arr<1,0>': unknown size,因此将大小添加1到完整的专业化解决了该错误。但是,它会在带有-pedantic标志的Ubuntu g ++ 8.1.0下进行编译。

我认为,对函数和类的完全专业化的行为就好像定义了非模板版本一样,因此我想这也应适用于变量模板,并且上面的完全专业化可以等同于(名称除外)

constexpr float arr_with_a1_and_b0[] = { 3.0f }; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer list-initialization template-variables c++17

5
推荐指数
1
解决办法
141
查看次数

对未知大小数组的引用的列表初始化:是否应该推断出数组大小?

以下代码在Clang中编译良好,并输出int [3]数组的大小

#include <iostream>

int main()
{
  const int (&a)[] = { 1, 2, 3 };
  std::cout << sizeof a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是,在GCC中,该声明可以很好地编译,但sizeof a不能编译:显然,GCC拒绝“推导”数组大小,最终a以引用const int []类型的方式结束,这是不完整的。

这种初始化的预期行为是什么?

在这种情况下,9.3.4 / 3似乎是标准的相关部分,但就其本身而言,似乎并不能得出结论。

c++ arrays reference list-initialization

5
推荐指数
1
解决办法
115
查看次数

为什么不对initializer_list中的值进行类型检查?

如何在没有任何警告或错误的情况下进行编译和运行?我不明白如何将current的int 取消引用值分配给字符串,a而不会出现任何问题。

class Test {
public:
  string a;

  Test(initializer_list<int> t) {
    auto current = t.begin();

    // I am assigning an int to a string!
    a = *current;
  }
};

int main() {
  Test test{65};
  printf("%s\n", test.a.c_str());
}
Run Code Online (Sandbox Code Playgroud)

打印的字符串是

A
Run Code Online (Sandbox Code Playgroud)

相反,此非常相似的代码会产生编译时错误:

int main() {
  initializer_list<int> test1{65};
  auto current = test1.begin();
  string b = *current;

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

错误是:

error: no viable conversion from 'const int' to 'std::__1::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
  string b = *current;
Run Code Online (Sandbox Code Playgroud)

c++ g++ std initializer-list list-initialization

5
推荐指数
1
解决办法
71
查看次数