3
class data
{
private:
    int ID;
    string address,name;
public:
    data(int i,string a,string n):ID(i),address(a),name(n){}
    friend class SetData;
};
class SetData
{
private:
    data obj(43,"185 Awan Market","Talha"); //this is where the error happens

public:
    void show()
    {
        cout<<"Name is: "<<obj.name<<endl;
        cout<<"Address is: "<<obj.address<<endl;
        cout<<"ID is: "<<obj.ID;
    }
};
juanchopanza
  • 223,364
  • 34
  • 402
  • 480

3 Answers3

7

C++03

It belongs in the constructor's mem-initializer:

class SetData
{
private:
    data obj;

public:
    SetData() : obj(43,"185 Awan Market","Talha")
    {
    }
    // Rest goes here...
};

C++11

You must use a brace or equal initializer.

// Fine
data obj{43,"185 Awan Market","Talha"};
// Fine, too
data obj = data(43,"185 Awan Market","Talha"); //this is where the error happens

For why parentheses are not allowed, see the Non-static data member initializers proposal. Scroll down to "An issue raised in Kona regarding scope of identifiers"

The motivation for class-scope lookup is that we’d like to be able to put anything in a non-static data member’s initializer that we could put in a mem-initializer without significantly changing the semantics (modulo direct initialization vs. copy initialization):

int x();

struct S {
    int i;
    S() : i(x()) {} // currently well-formed, uses S::x()
    // ...
    static int x();
};

struct T {
    int i = x(); // should use T::x(), ::x() would be a surprise
    // ...
    static int x();
};

Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed:

struct S {
    int i(x); // data member with initializer
    // ...
    static int x;
};

struct T {
    int i(x); // member function declaration
    // ...
    typedef int x;
};

One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it’s a function:

struct S {
    int i(j); // ill-formed...parsed as a member function,
              // type j looked up but not found
    // ...
    static int j;
};

A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it’s something else; and we can use “typename” if we really mean a type: Essentially

struct S {
    int i(x); // unabmiguously a data member
    int j(typename y); // unabmiguously a member function
};

Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “int i();” at block scope doesn’t declare a default-initialized int).

The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases, for example:

HashingFunction hash_algorithm{"MD5"};
user5254963
  • 168
  • 3
1

Initializing non-static data members in such a way is not allowed. You should rather be using a brace-or-equal initializer

class SetData
{
private:
    // data obj = {43,"185 Awan Market","Talha"}; is also valid
    data obj{43,"185 Awan Market","Talha"};

Cfr. non-static data members initialization

Alternative solution: constructor initializer list

class SetData
{
private:
    data obj;

public:
    SetData() : obj(43,"185 Awan Market","Talha") {}

    void show() 
    ...
};

As to why parenthesis are not supported for non-static data members initialization, I recommend reading this post: Why C++11 in-class initializer cannot use parentheses?

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
0

You can't initialize objects inline like that, you have to do it in the constructors initializer list:

class SetData
{
private:
    data obj;

public:
    SetData() : obj(43,"185 Awan Market","Talha") {}
    ...
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621