#How to initialize member variable without a default constructor in a class?

38 messages · Page 1 of 1 (latest)

trim hare
#

Ok, I've got the following situation in my project, Ive made a simplified example. How can I get the compiler to shut up and let me initialize it manually in the constructor?

#include <iostream>

struct FooBar {
    
    int b;
    
    FooBar() = delete;

    FooBar(int a) {
        this->b = a;
    }
    
};


struct Kal {
    
    FooBar foobar;
    Kal() {
        this->foobar = FooBar(4);
        
    }
};

int main()
{
    return 0;
}

vale notchBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

supple breachBOT
#
Compiler Output
<source>: In constructor 'Kal::Kal()':
<source>:19:11: error: use of deleted function 'FooBar::FooBar()'
   19 |     Kal() {
      |           ^
<source>:7:5: note: declared here
    7 |     FooBar() = delete;
      |     ^~~~~~
Build failed
trim hare
#

How can I get the compiler to shut up and let me initialize it manually in the constructor?

hexed linden
#
#include <iostream>

struct FooBar {
    
    int b;
    
    FooBar() = delete;

    FooBar(int a) {
        this->b = a;
    }
    
};


struct Kal {
    
    FooBar foobar;
    Kal() : foobar{4} {
    }
};

int main()
{
    return 0;
}

;compile

supple breachBOT
#
Compilation successful

No output.

light plank
#

use the initializer list

trim hare
#

Let me post a better simplified example, because this doesn't work in my case

trim hare
# light plank ?

Ive got a complex arrangement of linked classes that need to be constructed through a function so they're linked with one another. I want to keep one of these class as a member variable and pass the other two on

None of them are default constructable, they are only constructable through this function

light plank
#

meaning, use their existing constructors

trim hare
#

gimme a min,

#

you;re not understanding

#

Ok @light plank This is a much better example

#include <iostream>
#include <utility>

struct Foo;
struct Bar;

struct Foo {
    int a;
    
private:
    Foo(int a_i) : a(a_i) {}
    friend std::pair<Foo, Bar> createFooBar();
};

struct Bar {
    int b;
    
private:
    Bar(int b_i) : b(b_i) {}
    friend std::pair<Foo, Bar> createFooBar();
};

std::pair<Foo, Bar> createFooBar() {
    return std::make_pair<Foo, Bar>(
        Foo(3),
        Bar(3)
    );
}


class Kal {
public:  
    Kal() {
        auto [f, b] = createFooBar();
        
        this->foo = std::move(f);
        
        // do things with b, I end up spawning a thread ...
    }
    
private:
    Foo foo;
};

int main()
{
    auto kal = Kal();
    return 0;
}
#

;compile

supple breachBOT
#
Critical error:

You must attach a code-block containing code to your message or quote a message that has one.

supple breachBOT
#
Compiler Output
<source>: In constructor 'Kal::Kal()':
<source>:33:11: error: no matching function for call to 'Foo::Foo()'
   33 |     Kal() {
      |           ^
<source>:11:5: note: candidate: 'Foo::Foo(int)'
   11 |     Foo(int a_i) : a(a_i) {}
      |     ^~~
<source>:11:5: note:   candidate expects 1 argument, 0 provided
<source>:7:8: note: candidate: 'constexpr Foo::Foo(const Foo&)'
    7 | struct Foo {
      |        ^~~
<source>:7:8: note:   candidate expects 1 argument, 0 provided
<source>:7:8: note: candidate: 'constexpr Foo::Foo(Foo&&)'
<source>:7:8: note:   candidate expects 1 argument, 0 provided
Build failed
lost nimbus
#

int a = 0;
int a{};

trim hare
#

I'm just going to wrap it in a shared_ptr and call it a day with a lengthy comment

#

unless someone can come up with something good

trim hare
craggy lintel
#

@trim hare if the two objects are tightly intertwined to the point that they must be setup in pairs, and need a special helper construction function for that, then you just make a member pair and assign the pair returned by the helper function

#

You basically just bite the bullet and admit that that pair in that context just has special meaning and make that pair an actual type/entity

#

Another option is not to make a constructor but another helper that creates the pair in advance, then forward the two objects to a private constructor

#

Gets awkward if at some point you wish to emplace Kal into a container, but there are still workarounds arguably

#

As for your direct question, it just "doesn't make sense", if you need special extra processing you have to do that in a separate function before calling the constructor

#

Once you reach the body of a constructor, all the bases and members must have been constructed

#

You cannot just skip constructing one of those

#

Well I guess you "can", if you for example wrap a member whose construction you want to delay into an optional, but strictly speaking the optional will have been constructed as empty

#

Likewise for pointer-based solutions, the pointers will have been constructed, and you change their value to point to a dynamically object later on

#

Anyway, in terms of delaying member construction, I guess optional would be a tad more idiomatic?

vale notchBOT
#

This question thread is being automatically closed. If your question is not answered feel free to bump the post or re-ask. Take a look at !howto ask for tips on improving your question.