0

I am sure that I misunderstood something.

After instantiate a struct object inside class and pass it as value in constructor I get an error?

error: 'test' is not a type

#include <iostream>
using namespace std;

struct Test
{
    int x = 11;
    int y = 22; 
};

class A
{
private:
    int foo = 100;      
public:
    A(Test tmp){}
};
class B
{
private:
    Test test;
    A a(test);   //error    
public:
    B(){}   
};

int main()
{
    B b;    
    return 0;
}
Module_art
  • 999
  • 2
  • 9
  • 26
  • C++ is among the most case sensitive languages in the world. `Test` is the type, `test` is the B class member of type `Test`. Let us know if writing `A a(Test)` fixes your problem, then we can close the question as simple typo. – Cee McSharpface Apr 13 '18 at 14:31
  • 3
    @dlatikay "the most"? Are there case-half-caring and case-numb languages? – Quentin Apr 13 '18 at 14:32
  • just a silly joke. but who knows :) – Cee McSharpface Apr 13 '18 at 14:33
  • This is indeed a simple typo: either forgetting the type in a function declaration, or getting the case wrong, or using the wrong kind of brackets for default member init. My question is why you expected that to work in the 1st place! – underscore_d Apr 13 '18 at 14:37
  • @dlatikay: The only case-insensitive programming language I can think of is Visual Basic. Strange enough, SQL is case-insensitive, too. But the point is that C++'s case-sensitivity is hardly anything special in the world of software engineering. – Christian Hackl Apr 13 '18 at 14:46
  • Visual Basic, old FORTRAN (hello ASCII 1963, before lowercase existed...), SQL (mostly, except when it isn't... I'm looking at you dotted-Turkish-capital-i), Pascal. – Eljay Apr 13 '18 at 15:15

2 Answers2

6

If you want to declare a as a data member and initialize it, the correct syntax should be:

class B
{
private:
    Test test;
    A a{test};       // default member initializer    
    A a = test;      // default member initializer    
    A a = A(test);   // default member initializer    
public:
    B() : a(test) {} // member initializer list   
};

Note that default member initializer only support brace or equals but not parentheses initializer. And it is used only if the member is omitted in the member initializer list.

The compiler is trying to interpret a as a function, which returns A and taking test as parameter. test is not a type name then compiling fails.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • I wish OPs example not be a most vexing parse (is it actually?!), as for the compiler it should be pretty easy to realize that's not a function definition. Still wonder why cases like those are not "updated" in the C++ standard. – vsoftco Apr 13 '18 at 14:52
  • @vsoftco The standard just doesn't allow parentheses initializer for default member initializer, I wonder why too; but I think most vexing parse is irrelevant here, because `Test test; A a{test};` is pretty fine if you put it inside a function; it's just not allowed for default member initializer. – songyuanyao Apr 13 '18 at 15:03
  • Thank you. "If you want to declare a as a data member and initialize it" that was the idea I was not correct with "instantiate a struct object inside class" and I miss that isn't possible to call A a(test) like usually from a function. – Module_art Apr 13 '18 at 16:10
1

After [I] instantiate a struct object inside class...

class B
{
    private:
        Test test;

This is not instantiating anything. This declares that every (at this point, theoretical object of type B will have a member variable named test, of type Test.

(Besides, get into the habit of making any member variable private, not public, as early on in your learning process as possible. A class is not just a struct with functions, it is an elementary OOP building block that should not expose its data members to public -- doing so is usually a design error.)

        A a(test);   //error    

This is not "passing [test] as parameter to a constructor", as you stated!

This is declaring a member function to class B named a, which returns an object of type A, and takes an unnamed parameter of type test.... which, as there is no such type, just a member variable of that name, this an error.

As the overall purpose of your code example is rather unclear, it is difficult to say what would be "correct" for you.

DevSolar
  • 67,862
  • 21
  • 134
  • 209