3

I'm getting the compile error structure required on left side of . or .* on chest.contents[0], but chest is a structure:

class Item {
public:
    int id;
    int dmg;
};

class Chest {
public:
    Item contents[10];
};

int main() 
{
    Chest chest();

    Item item = chest.contents[0];

    return 0;
}
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
Max
  • 51
  • 1
  • 6
  • You meant to say `chest` is an object, but that's still wrong. – chris May 21 '13 at 21:47
  • @chris: He's using "structure" in the same sense the compiler error message is, meaning "an object which is an instance of a class type". And yes, that assertion is wrong. – Ben Voigt May 21 '13 at 21:48
  • 8
    This error is so notorious that there is a tag for it... it is called the "Most Vexing Parse". – Dietrich Epp May 21 '13 at 21:49
  • @BenVoigt, That's odd. I didn't see the exact error, but I've never heard an object called a structure, unless it's supposed to be a different meaning. – chris May 21 '13 at 21:49
  • 3
    @DietrichEpp: This is closely related to most vexing parse, but not actually it. Most vexing parse is: `T t(S());` where `S` and `T` are types and `S()` is intended to construct a temporary object to be passed to a converting constructor. It's considerably more problematic than this because the fix is so subtle and often gets removed during code cleanup efforts. – Ben Voigt May 21 '13 at 21:52
  • @chris: For example, the explanation for [C2231](http://msdn.microsoft.com/en-us/library/y2z7czs3.aspx). To be pedantic, it should say "*the type of* the operand to the left", or "*an instance of* a class, structure, or union". – Ben Voigt May 21 '13 at 21:59

2 Answers2

12

No it isn't, it's a function that takes zero parameters.

To default-initialize a variable, use

Chest chest;

In C++11, this syntax can be used for value-initialization.

Chest chest{};

In C++03, that needs a complicated (because of many compiler bugs) workaround, which the Boost library thankfully has made easy to use:

boost::value_initialized<Chest> chest;
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Also known as [most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse). – bitmask May 21 '13 at 22:18
  • @Bitmask: It's not. Did you read the comments under the question? Or your link? – Ben Voigt May 21 '13 at 22:22
  • @BenVoigt: That rather depends how you quantify vexation. I'd say that before 2011 this was more vexing, since as you say it needed weird magic to resolve in general, rather than a simple pair of parentheses. These days, they're about as vexing as each other. – Mike Seymour May 21 '13 at 23:41
  • @BenVoigt: Now I did. As far as I am concerned this is the same phenomenon. Parentheses that were intended to denote the default constructor call were instead interpreted as parentheses around the (possibly empty) formal parameters in a function declaration. – bitmask May 22 '13 at 11:10
6
Chest chest();

Is not as you might believe, a call to the constructor

Chest::Chest();

But rather the declaration of a function. The proper way to create your chest is

Chest chest;

It is only when you have defined constructors that takes arguments you should use the parenthesis.

string s;
string s2("Hello");
Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67