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 1 year ago.
Is it correct to use the member of a struct that we are initializing? My compiler does not complain with the following code:
#include <iostream>
struct Foo {
int a, b;
};
int main() {
Foo foo {34, foo.a + 2}; // I'm using `foo.a` during the `foo` initialization
std::cout << foo.a << " " << foo.b << std::endl;
return 0;
}
// Prints "34 36"
But it seems weird since foo is not declared yet when I use it inside the braces.
This is fine and valid as long as you keep a declared before b as you're doing right now.
Related
This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
Pass Member Function as Parameter to other Member Function (C++ 11 <function>) [duplicate]
(2 answers)
Passing a pointer to a class member function as a parameter
(2 answers)
Closed 24 days ago.
I am trying to create object of another class in one class (I am able to do this) and I want to pass a method of the first class to the second class as constructor argument (I am not able to do this. I get compiler errors). Below is the code.
#include <iostream>
using namespace std;
class B
{
public:
B(void (*fp)(void))
{
fp();
}
private:
};
class A
{
public:
void printHelloWorld()
{
cout << "Hello World!" << endl;
}
private:
B ObjB{printHelloWorld};
};
int main()
{
cout << "!!** Program Start **!!" << endl;
A ObjA;
cout << "!!** Program End **!!" << endl;
return 0;
}
I receive the following Errors.
main.cpp:21:27: error: could not convert ‘{((A*)this)->A::printHelloWorld}’ from ‘’ to ‘B’
21 | B ObjB{printHelloWorld};
| ^
| |
| <brace-enclosed initializer list>
The code can be compiled on this link also
https://onlinegdb.com/xB70hwQph
The code works fine if I make printHelloWorld as static function or Shift the defination of printHelloWorld outside the class.
I am looking for a solution for this simple looking problem.
You cannot use a non-static method as an argument for a C style function pointer parameter.
The reason is that in order to invoke it you need a this pointer which is not available with a C function pointer.
You can use std::function, together with a lambda capturing this to achieve what you need.
However - since you initialize your ObjB directly when it is declared, the complete A might not have been fully constructed yet (e.g. via a specific contructor) and therefore calling the method directly from B's constructor is problematic. In your trivial case it can work, but imagine the method printHelloWorld accessing some A members.
Instead I made B store the std::function so that it can later be invoked via the invokeF() method.
Code example:
#include <iostream>
#include <functional>
class B
{
public:
//----vvvvvvvvvvvvvvvvvvvvvvvvv----
B(std::function<void(void)> fp) { m_fp = fp; }
void invokeF() { m_fp(); }
private:
std::function<void(void)> m_fp;
};
class A
{
public:
void printHelloWorld() { std::cout << "Hello World!" << std::endl; }
void invokeBF() { ObjB.invokeF(); }
private:
//----------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv----
B ObjB{ [this]() { printHelloWorld(); } };
};
int main()
{
std::cout << "!!** Program Start **!!" << std::endl;
A ObjA;
ObjA.invokeBF();
std::cout << "!!** Program End **!!" << std::endl;
return 0;
}
Output:
!!** Program Start **!!
Hello World!
!!** Program End **!!
Demo (Godbolt)
A side note: Why is "using namespace std;" considered bad practice?.
This question already has answers here:
Is it true that a default constructor is synthesized for every class that does not define one?
(6 answers)
Closed 3 months ago.
in following code:
`
#include <iostream>
struct MyStruct {
int i = 1;
};
int main() {
MyStruct(some); // some is actually a variable name, it compiles, is it in the
// c++ standard?
std::cout << some.i << std::endl;
}
`
why can i initialzie MyStruct(some)?
above code compiles and runs
I doubt that the variable "some" in the first code is a variable, it wouldn't run when I try to declare a variable called some.
But your problem with this code...
struct MyStruct {
MyStruct(const int &value) {}
};
int main() {
std::string(s2);
MyStruct(some); // illegal now
std::cout << s2 << std::endl;
}
is that you don't have an identifier for the MyStruct that you are instantiating.
struct MyStruct {
MyStruct(const int &value) {}
};
int main() {
int some = 5;
std::string(s2);
MyStruct myStruct (some); // illegal now
std::cout << s2 << std::endl;
}
Here I placed "myStruct" as the identifier for the "MyStruct". I also declared a variable called "some" to check if it runs that way, which it does.
The way of declaring and defining a variable is very wired. If you want to define std::string and MyStruct, you are supposed to use the following way: std::string s2("initialized value"); MyStruct some. In your second case, MyStruct has defined a constructor so the default constructor in the first case doesn't exist anymore unless you explicitly define it.
So in the second case, if you want to initialize an instance with one argument, the following is a supported way:MyStruct some(10);. This statements call the constructor you write.
This question already has answers here:
How can I declare a member vector of the same class?
(1 answer)
Incomplete type error when using std::vector with structs
(1 answer)
Closed 3 years ago.
In the following sample code, C++ allows container of self class. But if a single object is created it's not allowed. I understand that class can have pointer to self type or static member object.
But how is container of self (not self pointer) is allowed? How is compiler able to get 'complete definition' for vector members?
#include <iostream>
#include <vector>
class Test {
std::vector<Test> list; //but this works
static Test t3; // this is allowed too
// Test t2; // definition of 'class Test' is not complete
public:
Test() {
std::cout << "Test()" << std::endl;
std::cout << list.size() << std::endl;
}
};
int main() {
Test t;
return 0;
}
This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 3 years ago.
now I am just really new to C++, currently I have a piece of code below:
#include <iostream>
using namespace std;
template<typename T>
class Test1
{
public:
Test1():var1(1) {
cout << "Constructor1" << endl;
}
Test1(T a):var1(a) {
cout << "Constructor2" << endl;
}
private:
int var1;
};
template<typename T>
class Test2
{
public:
Test2():var2(x) {
cout << "Constructor3" << endl;
};
private:
int x;
Test1<int> var2;
};
int main()
{
Test2<int> var3;
return 0;
}
The output will just be
Constructor2
Constructor3
I wonder why the constructor2 will be called instead of constructor1, since in the class Test2, when creating the object var2, I didn't pass in any parameters, shouldn't the constructor without parameter being called?
Thank you in advance!
The constructor for a variable is determined by its initialization. You have an initialization list on your Test2 constructor
Test2():var2(x) {
so you have to look there for how Test2::var2 is initialized. In the initialization list, you're passing the integer x (that's not initialized to anything), so it calls the Test1 constructor that takes an integer.
If you don't explicitly initialize var2 in your initializer list (for example, if you just assign to it in the constructor body), then it will be default initialized and say "constructor 1" instead of 2
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.