5

In the following example the forward declaration the struct Y foward declaration is not enough. If you comment out X::b, it compiles fine, since Y has a full struct declaration to work with, but X only has the forward declaration.

#include <functional>
#include <iostream>

struct Y;

struct X
{
    std::function<bool(Y&)> b{[] (auto& y_) { return y_.a; }};

    bool a{false};
};

struct Y
{
    std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }};

    bool a{true};
};

int main()
{
    return 0;
}

Ideone

The following is the fix I could come up with:

#include <functional>
#include <iostream>

struct Y;

struct X
{
    X();
    std::function<bool(Y&)> b;

    bool a{false};
};

struct Y
{
    Y();
    std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }};

    bool a{true};
};

X::X() : b([] (auto& y_) { return y_.a; }) {}
Y::Y() : b([] (auto& x_) { return x_.a; }) {}

int main()
{
    return 0;
}

Ideone

And while it works in this example, if the classes were polymorphic, this would require using X::X; or using Y::Y; in children of those classes respectively.

Is there a way to do this in the header files themselves?

Post Self
  • 1,471
  • 2
  • 14
  • 34
  • 2
    Why would you need e.g. `using X::X` in a child-class? The constructor is still *declared* inside the class, it's just *defined* (implemented) outside of the class-definition (i.e. it's not inline). – Some programmer dude Aug 04 '17 at 18:46
  • Is it? Let me try it – Post Self Aug 04 '17 at 18:53
  • 1
    All you should need is [proper header/implementation structure](https://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies) and instead of initializing the members in the class body do it in the constructor initialization list. – NathanOliver Aug 04 '17 at 18:55
  • @Someprogrammerdude Oh, you are right: http://ideone.com/39qcEG – Post Self Aug 04 '17 at 18:56
  • @Someprogrammerdude If you write that as an answer, I'll accept it – Post Self Aug 04 '17 at 18:57
  • @NathanOliver I am writing a paper where it's good seeing the default values in the class definition, but I'll keep it in mind for future projects. – Post Self Aug 04 '17 at 19:42

1 Answers1

0

You could do this:

#include <functional>

template <typename T> bool (*get_lambda())(T&) {return [] (auto& y_) { return y_.a; };};

struct Y;

struct X
{
    std::function<bool(Y&)> b{get_lambda<Y>()};

    bool a{false};
};

struct Y
{
    std::function<bool(X&)> b{get_lambda<X>()};

    bool a{true};
};

int main()
{
    return 0;
}
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207