3

For example:

struct Spell 
{
    int id;
    vector<int> cost(4);
};

It says

'Expected parameter declaration'.

Also does this piece of code have a difference?

if (can(vector <int>inv, spell.cost)) 
{
    cout << "CAST " << spell.id << endl;
    done = true;
    break;
}

This one says

'Expected '(' for function-style cast or type construction'
        
        

Could by any chance lend me a hand?

doogy
  • 31
  • 5
  • 1
    It's funny how everyone understands that this can't be a function because of the rvalue, just the compiler doesn't. – Thomas Weller Oct 23 '22 at 17:31
  • @ThomasWeller The compiler should understand that, too: This cannot be parsed as a function declaration, can it? The Wikipedia example for the most vexing parse id different: `int i(int(my_dbl));` is a function declaration that happens to have redundant parentheses around its parameter name. `4`, on the other hand, cannot be a function parameter declaration, so the line cannot declare a function. What am I missing? – Peter - Reinstate Monica Oct 23 '22 at 19:24

1 Answers1

6

As mentioned in the member initialization section in cppreference.com:

Non - static data members may be initialized in one of two ways :

  1. In the member initializer list of the constructor.

    struct S
    {
        int n;
        std::string s;
        S() : n(7) {} // direct-initializes n, default-initializes s
    };
    
  2. Through a default member initializer, which is a brace or equals initializer included in the member declaration and is used if the member is omitted from the member initializer list of a constructor.

    struct S
    {
        int n = 7;
        std::string s{ 'a', 'b', 'c' };
        S() {} // default member initializer will copy-initialize n, 
               // list-initialize s
    };
    

As per the above (emphasis mine), your member declaration is wrong.

I assume that, your intention was to have a vector of ints (i.e cost) as member and allocate 4 integers and default (value)initialize them .

You can fix it by either of the following ways:

  1. uniform - braced initialization
    struct Spell {
        int id;
        std::vector<int> cost{ std::vector<int>(4) };
        //                  ^^^                  ^^^^
    };
    
  2. equals initializer
    struct Spell {
        int id;
        std::vector<int> cost =  std::vector<int>(4); // or decltype(cost)(4)
        //                   ^^^^^^^^^^^^^^^^^^^^^^^^
    };
    
  3. provide a constructor and in constructor member initializer
    struct Spell { 
        int id; 
        std::vector<int> cost;
        Spell()
            : cost(4) // constructor member initializer
        {} 
    };
    

Since std::vector has the std::initializer_list constructor, unfortunately you can not write std::vector<int> cost{ 4 }, as it will be interpreted, the 4 being a single vector element.

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 1
    LOL, one gotta love C++. Most intuitive way of initializing a vector with a given size. I'd probably prefer omitting `(4)` completely over doing this, especially because the number is so small. – Thomas Weller Oct 23 '22 at 17:26
  • 3
    The alternative is to add a constructor to the struct, eg: `struct Spell { int id; std::vector cost; Spell() : cost(4) {} };` – Remy Lebeau Oct 23 '22 at 17:57
  • 1
    This case doesn't have anything to do with the most vexing parse, because of the literal `4` inside `()`. There's no way to parse that as a function declaration afaik. After all, how could `4` be a type? – cigien Oct 24 '22 at 06:20