1

I'm trying to specify an attribute of a class as being a array of 5 position of the type Stock like follows:

#include "stdio.h"
#include "string"
#include "array"
#include "./stock.h"

#ifndef WALLET_H

class Wallet {
  public:
    Wallet(std::string name, Stock stocks[5]) : name_(name), stocks_(stocks) {}

    //! Calculate de wallet return
    float wallet_return(Stock *stock);

    //! Return the name of the wallet
    std::string get_name();

    //! Return all the stocks in the wallet
    Stock* get_stocks();

  private:
    std::string name_;
    Stock stocks_[5];
};

#endif

std::string Wallet::get_name() {
  return name_;
}

Stock* Wallet::get_stocks() {
  return stocks_;
}

But I keep getting the error invalid initializer for array member 'Stock Wallet::stocks_ [5]', referring to the constructor method.

What I'm I doing wrong?

Ian Guimarães
  • 371
  • 3
  • 12
  • 3
    Try `std::array stocks` and `std::array stocks_;` instead (add `#include `). Raw c-style arrays cannot be copied, that's the reason for the compiler error – πάντα ῥεῖ Oct 28 '20 at 23:45
  • Thank you, that worked as a charm. About the "Raw c-style arrays cannot be copied" part, in c there is no way to pass as argument an fixed size array like I was trying to do? – Ian Guimarães Oct 28 '20 at 23:54
  • Arrays are an elegant solution to the problems of the 1970s. You can't pass an array. This was too expensive back when RAM was measured in bytes and processor speeds in Kilohertz. [All you can do is pass a pointer to an array](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay). You can stick an array inside a structure and pass that structure. That's part of what `std::array` does. – user4581301 Oct 29 '20 at 00:01

1 Answers1

2

In your Wallet() constructor, the Stock stocks[5] parameter is just syntax sugar, the compiler is actually passing Stock *stocks instead. A fixed-size array can be passed in a parameter only by reference or pointer. But you can't initialize an array from a pointer, which is why your code fails to compile.

In this case, you can either pass the input array by reference:

class Wallet {
  public:
    Wallet(std::string name, Stock (&stocks)[5]) : name_(name), stocks_(stocks) {}

    ...
};

Live Demo

Or, you can use std::array instead:

#include <array>

class Wallet {
  public:
    Wallet(std::string name, std::array<Stock, 5> &stocks) : name_(name), stocks_(stocks) {}

    ...

    Stock* get_stocks();

  private:
    ...
    std::array<Stock, 5> stocks_;
};

#endif
Stock* Wallet::get_stocks() {
  return stocks_.data();
}

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You can't initialize an array with an array reference. Array initializers have to use braces to do aggregate initialization. examples: https://godbolt.org/z/nYx797 https://ideone.com/Bu8CrF. `std::array` is the best method here without writing `Wallet(std::string name, const Stock (&stocks)[5]) : name_(name), stocks_{stocks[0], stocks[1], stocks[2], stocks[3], stocks[4]} {}` – Artyer Oct 29 '20 at 01:32
  • "*You can't initialize an array with an array reference*" - and yet, it works in the demo I posted – Remy Lebeau Oct 29 '20 at 01:56
  • 1
    This is a gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59465. It doesn't work in clang/msvc/icc (and probably most other compilers). And it wouldn't even work in gcc if `Stock` was a typedef for `int`/another non-class type. – Artyer Oct 29 '20 at 18:45