Constructor using {a,b,c} as argument or what is {a,b,c} actually doing?
Asked Answered
R

3

6

I know, that I can initialize data like this.

int array[3] = { 1, 2, 3 };

or even

int array[2][2] = { {1, 2}, {3, 4} };

I can also do it with std::vector

std::vector<int> A = { 1, 2, 3 };

Let's say I want to write my own class:

class my_class
{
     std::vector< int > A;
     public:
     //pseudo code
           my_class(*x) { store x in A;} //with x={ {1, 2}, {3, 4} }
     // do something
};

Is it possible to write such a constructor and how is it possible? What is this statement

{{1, 2}, {3, 4}} actually doing?

I always just find, that you can initialize data in this way, but never what it is doing precisely.

Rachellerachis answered 23/5, 2018 at 13:7 Comment(3)
en.cppreference.com/w/cpp/language/list_initializationInalterable
Write a ctor accepting std::initializer_list as an argument.Dictaphone
I think, that's it, thanks, I didn't knew the word list_initialization, so I couldn't find it.Rachellerachis
F
10

It is called list initialization and you need a std::initilizer_list constructor, that to be achieved in your my_class.

See (Live Demo)

#include <iostream>
#include <vector>
#include <initializer_list> // std::initializer_list

class my_class
{
    std::vector<int> A;
public:
    // std::initilizer_list constructor 
    my_class(const std::initializer_list<int> v) : A(v) {}    

    friend std::ostream& operator<<(std::ostream& out, const my_class& obj) /* noexcept */;
};

std::ostream& operator<<(std::ostream& out, const my_class& obj) /* noexcept */
{
    for(const int it: obj.A) out << it << " ";
    return out;
}

int main()
{
    my_class obj = {1,2,3,4};  // now possible
    std::cout << obj << std::endl;
    return 0;
}
Futrell answered 23/5, 2018 at 13:11 Comment(0)
L
3

You can use initializer_list in the constructor to have such option.

struct X {
    X() = default;
    X(const X&) = default;
};

struct Q {
    Q() = default;
    Q(Q const&) = default;
    Q(std::initializer_list<Q>) {}
};

int main() {
  X x;
  X x2 = X { x }; // copy-constructor (not aggregate initialization)
  Q q;
  Q q2 = Q { q }; // initializer-list constructor (not copy constructor)
}
Loidaloin answered 23/5, 2018 at 13:14 Comment(2)
is there a need for a copy constructor?Tabbi
Yes it is required. Q(Q const&) = delete; will through error at compile time initializer-list constructor (not copy constructor).Loidaloin
T
3

how is it possible?

If you have an initializer list.

#include  <initializer_­list> // use std::initializer_list template
my_class(const std::initializer_list<int>& v) : A(v) {}

What is this statement "{{1, 2}, {3, 4}}" actually doing?

This is called list-initialization

If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized.

Tabbi answered 23/5, 2018 at 13:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.