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;
}
};

- 223,364
- 34
- 402
- 480

- 33
- 1
- 1
- 3
-
NSDMI supports only brace-or-equal initializers – Piotr Skotnicki Aug 22 '15 at 11:53
3 Answers
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"};

- 168
- 3
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?
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") {}
...
};

- 400,186
- 35
- 402
- 621