What's the output of the following code? [duplicate] - c++

This question already has answers here:
Why does this call the default constructor?
(3 answers)
Closed 9 years ago.
This code was published in http://accu.org/index.php/cvujournal, Issue July 2013.
I couldn't comprehend the output, any explanation would be helphful
#include <iostream>
int x;
struct i
{
i() {
x = 0;
std::cout << "--C1\n";
}
i(int i) {
x = i;
std::cout << "--C2\n";
}
};
class l
{
public:
l(int i) : x(i) {}
void load() {
i(x);
}
private:
int x;
};
int main()
{
l l(42);
l.load();
std::cout << x << std::endl;
}
Output:
--C1
0
I was expecting:
--C2
42
Any Explanation ?

i(x); is equivalent to i x;, with a redundant pair of parentheses thrown in. It declares a variable named x of type i, default-initialized; it does not create a temporary instance of i with x as the constructor's parameter. See also: most vexing parse

Related

Initialization of member variable via parentheses doesn't work [duplicate]

This question already has an answer here:
Why class data members can't be initialized by direct initialization syntax?
(1 answer)
Closed 11 months ago.
For the following codes, can anyone explain why we can't initialize the variable data by parentheses?
#include <iostream>
using namespace std;
class X
{
private:
int data(1); // wrong here
public:
void print()
{
cout << data << endl;
}
};
int main()
{
X temp;
temp.print();
return 0;
}
There isnt actually much to explain, its just not valid syntax. Default member initializers are
class X
{
private:
int data{1}; // ok
int data2 = 42; // also ok
public:
void print()
{
cout << data << endl;
}
};
While int data(1); is not valid syntax for a default member initializer. See here for details: https://en.cppreference.com/w/cpp/language/data_members

Aggregate Initialization of struct with dependent fields [duplicate]

This question already has answers here:
Is it defined behavior to reference an early member from a later member expression during aggregate initialization?
(4 answers)
Closed 4 years ago.
Is it legal to do the following?
#include <iostream>
struct Foo
{
int bar;
int baz;
};
int main()
{
Foo instance = { 5, instance.bar };
std::cout << instance.baz << std::endl;
}
I think it's not because as far as I know the order of initialization is unspecified and the bar field can be initialized after baz.
Am I right?
https://coliru.stacked-crooked.com/a/ea97713515dd0687
If you liked your conundrum, this is really gonna bake your noodle:
#include <iostream>
struct Foo
{
int bar=0;
int baz=1;
};
const int cool(const Foo& f)
{
std::cout << "Bar: " << f.bar << " Baz: " << f.baz << std::endl;
return f.bar;
}
int main()
{
Foo instance = { 5, cool(instance) };
std::cout << instance.baz << std::endl;
}
What a previous poster correctly quoted: c++ std draft doc
...all value computations and side effects associated with a given element are sequenced before those of any element that follows it in order.

(C++) why static member can be used before it is initialized? [duplicate]

This question already has answers here:
When are static C++ class members initialized?
(7 answers)
Closed 4 years ago.
I write this test code:
#include <iostream>
using namespace std;
class Date {
int d;
int m;
int y;
public:
static Date default_date;
public:
Date(int d, int m, int y) {
default_date.display();
this->d = d ? d : default_date.d;
this->m = m ? m : default_date.m;
this->y = y ? y : default_date.y;
}
void display() { std::cout << d << "-" << m << "-" << y << std::endl; }
};
Date Date::default_date(25, 12, 2018);
int main() {
Date d = Date(0, 0, 0);
d.display();
Date::default_date.display();
}
and the output is:
0-0-0
25-12-2018
25-12-2018
25-12-2018
OK, here is my question.
The static member default_date is initialized outside the class definition and using the constructor of class.
However, when the constructor is called, it seems that default_date already exists. I even execute default_date.display() and get the output 0-0-0.
Why I can visit default_date before it is constructed/initialized?
The first time the constructor is called is the point of initialization of default_date. And inside this constructor, before the members are assigned their supposed values, the constructor constructor calls display(), which prints zero-initialized values of the members.

C++: virtual function calling parent [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 6 years ago.
#include <iostream>
using namespace std;
struct A
{
virtual int func(void) { return 0; }
};
struct B : A
{
int func(void) { return 1; }
};
int main()
{
A b = B();
cout << b.func() << endl;
}
I was expecting the output to be 1 but as most of you will know its 0.
what i want to achieve in my actual code is something along these lines.
struct A
{
virtual int operator() (int i);
};
struct B : A
{
int operator() (int i) { return i*2; }
};
struct C : A
{
int operator() (int i) { return i*3; }
};
struct x
{
A test;
};
So my container won't be able to tell before hand if it will hold a A, B or C, but should behave differently still.
Is there a way to achieve the functionality as I anticipated it work??
A b = B();: you're constructing an object of type A, using the assignment operator/copy constructor (through copy elision) from a B object, but seen as a reference to A (which explains why it compiles without errors)
This isn't polymorphism. b is still of type A. The link to B has been lost.
That would do it:
A *b = new B();
now
cout << b->func() << endl;
triggers polymorphism/virtual function and yields 1 as expected.
C++ virtual functions only works for references/pointers, which means indirections.
A b = B();
This creates an object of type A, not of type B. No indirection, therefor only the function in A is called.

What's a good way to capture member variable by value in c++11? [duplicate]

This question already has an answer here:
C++11 lambdas: member variable capture gotcha
(1 answer)
Closed 7 years ago.
struct myclass {
myclass(){}
myclass(int qx):z(qx){ }
std::function<void()> create() {
auto px = [z](){
std::cout << z << std::endl;
};
return px;
}
int z;
};
myclass my;
my.z = 2;
auto func = my.create();
func();
my.z = 3;
func();
This code will compile in gcc 4.6.3, which will do the correct thing to make a copy of member variable z, and both print will get 2. In gcc 4.8.2 this doesn't compile anymore..
error: 'this' was not captured for this lambda function
I wonder why this functionality was removed as it was quite useful.
I don't think you can do this directly in C++11 (see #Nawaz's comment for a workaround). However, C++14 helps exactly in this instance, via generalized lambda captures:
auto px = [v = this->z]() // capture by value just ONE member variable
{
std::cout << v << std::endl;
};
Example:
#include <functional>
#include <iostream>
struct myclass {
myclass(): z{} {}
myclass(int qx): z(qx) { }
std::function<void()> create() {
auto px = [v = this->z]() {
std::cout << v << std::endl;
};
return px;
}
int z;
};
int main()
{
myclass my;
my.z = 2;
auto func = my.create();
func();
my.z = 3;
func();
}
Live on Coliru
Lambdas can only capture members of the local scope in which they are declared. They can't capture member variables, by copy or by reference.
However, C++14's generalized lambda capture can get the job done:
auto px = [z = z](){
std::cout << z << std::endl;
};
You could qualify the inner z with this->z to make it clear what you're doing.
If C++14 is not available, you can make the capture explicit by creating a temporary variable in your function, which will be captured:
auto z = this->z;
auto px = [z](){
std::cout << z << std::endl;
};