This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 4 years ago.
I'm sorry, I haven't programmed C++ in a while, I'd like to refresh my knowledge about what exact rule I'm violating here:
I can do:
int main()
{
int a(5);
}
but cannot do:
struct Foo
{
int a(5); // Error: expected a type specifier / Error: syntax error, 'constant'
}
I am trying to regain some lost knowledge, can someone direct me to the rule that disallows this? I'm pretty sure there'd be a question about it on here, I couldn't find it. The only thing I remember is that the committee debated (for C++11 I think) in class constructor arguments and introduced new squiggly bracket constructor initialisers, like int a{5}; but I would like to know why int a(5); isn't allowed inside a class. Has this always been disallowed in C++?
A species of vexing parse. Names in default member initializers are supposed to be looked up in the completed class, because they are suppose to imitate constructor initializers. With (), the compiler won't be able to figure out what it's parsing, because it can refer to things declared later in the class:
struct X {
int f(x); // function or data member?
static const int x = 1;
};
Related
This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Initialization of member variable via parentheses doesn't work [duplicate]
(1 answer)
can not define and init a class member by Parentheses [duplicate]
(1 answer)
Closed 9 months ago.
I'm trying to neatly create a objects within a class and I've run into what seems to me to be an odd limitation in c++, and I wondered if I'm just missing a syntax trick or whether it's truly impossible; specifically it seems like I cannot explicitly instantiate a class object inside another class if the constructor of the former has parameters (the parameters are constant) generating the odd message: 'Expected parameter declarator'
It seems as though only default constructors are supported in this scenario, or am I missing a bit of magic?
Currently using c++17 (simply because that's the default in this IDE)
class Fred
{
public:
Fred(const int i)
{
}
Fred()
{
}
};
Fred fred1(0); // This compiles
class Charlie
{
Fred fred2(); // This compiles
Fred fred3(0); // This does not compile
};
This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 7 months ago.
I have a line of code inside a class's private member variables:
vector<double> dQdt(3)
When compiling in xcode, this gives an error "expected parameter declarator." I think I provided sufficient info. I don't see anything wrong with this declaration.
You have to initialize the variable in the constructor's initializer list:
class X
{
private:
vector<double> dQdt;
public:
X() : dQdt(3) {}
};
If you read e.g. this member initialization reference you will learn that default member initialization have to be a brace or equals initializer. I.e. you need to either use curly-braces:
std::vector<double> dQdt{ 0.0, 0.0, 0.0 };
or using the equals character:
std::vector<double> dQdt = std::vector<double>(3);
Since this was introduced with the C++11 standard, you need to enable that in your environment.
I got this error while trying to compile my C++ code having an initialized vector.
Change the () to {} worked for me in the initialization part;
Earlier my code looked like this:
vector<vector<int>> minA(11, vector<int>(11, INT_MAX));
I changed my code to replace circular brackets with curly braces and the error disappered.
vector<vector<int>> minA{11, vector<int>(11, INT_MAX)};
The parameter for constructors of data members should be written in the initializer list of your class' constructor. That is, instead of
class Foo {
vector<double> dQdt(3);
};
You should write
class Foo {
public:
Foo() : dQdt(3) {}
private:
vector<double> dQdt;
};
As well as initializing in the initializer list of the constructor, you can initialize with a brace initializer list:
class Foo {
vector<double> dQdt{3};
};
The actual text of the error is because the compiler was expecting you to declare a function, taking an argument of some type, and return the vector<double>. 3 is not a valid declaration of a parameter to a function.
The question is already answered the following however works as well.
( Which might be more useful to assign initial values. For example 24 times the 42. )
const int default_value = 42;
struct foo
{
vector<double> hour{vector<double>(24,default_value)};
};
This question already has answers here:
Initialize static variables in C++ class?
(9 answers)
Closed 2 years ago.
I have never seen this:
class myclass{
static int value;
};
int myclass::value(5);
This is a short version of a code that i see in the book C++ Concurrency in Action, but i don't get what is that declaration of a static class value out of the class block like that.
:: is known as scope resolution operator and one of the purpose of it is to access a class’s static variables outside class and it seems above piece of code is doing same initializing it outside class.
One of the ways to initialize variables in c++, known as constructor initialization, is done by enclosing the initial value between parentheses (()):
So int myclass::value(5); is equivalent to int myclass::value = 5;
This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 5 years ago.
I have 2 test classes:
class B {
public:
B(int i) {
qDebug() << "B constructor ";
}
};
class A {
public:
A(B b) {
qDebug() << "A constructor ";
}
};
Now i want to create A object with B, thats what i do:
int i = 5;
A test (B(i)); //does not work
Code compiles without errors, but second line doesnt execute at all. I've made some tests, and code below works well:
int i = 5;
A test (B((int)i)); //works
A test (B(5)); //works
So, i guess compiler cant interpret 'i' as int inside B constructor call, but why?
This:
A test(B(i));
is the same as the:
A test(B i);
which is a function declaration, not a call to constructor due to a most vexing parse.
There is a rule that states (S. Meyers, "Effective Modern C++"):
anything that can be parsed as a declaration must be interpreted as
one
To avoid that use braced initialization (instead of parentheses ()) as functions can't be declared with {} braces:
A test{B(i)};
That being said there are no "nested constructors calls" in your example.
This question already has an answer here:
Why can in-class initializers only use = or {}? [duplicate]
(1 answer)
Closed 5 years ago.
I'm just going through the basic OOP concepts in C++ and came across the following:
class A{
public:
int i(20); //line 1
};
int main()
{
int j(20);
cout<<j<<endl;
A obj;
cout<<obj.i<<endl;
}
I get the following error at line1 when compiling (tried in both gcc and MSVC++),
expected identifier before numeric constant
I know how to assign default value for a non-static member (which can be done from C++11 on wards in different ways), but I couldn't get the reason why only this kind of default value initialization is not possible as doing the same initialization (for normal variables) anywhere else is valid.
What could be the reason for such restriction?
Edited:
From the links and answer provided, it is because "it might read as function declaration in some cases. Because of this ambiguity, it is not allowed."
But consider the following case:
//global scope
struct B{
int j;
};
int B = 10;
int object(B);
This is also a similar case, where int object(B) might be understood as a function object taking B object as argument and with int return type.
I tried this in gcc and MSVC++ and object is treated as an int variable. Why it is not restricted in this case?
Using parentheses was deemed to be too confusing since it would read very similarly to a function declaration. Think about the case of a default constructor:
class A{
public:
int i(); // function declaration -- did you mean to
// use the default constructor instead?
};
There are other ways to do it though:
class A{
public:
int i = 20;
int i{20};
int i = {20};
};