Try to understand compiler error message: default member initializer required before the end of its enclosing class
This is a clang and gcc bug, we have a clang bug report for this: default member initializer for 'm' needed within definition of enclosing class for default argument of function which has the following example:
#include <limits>
class A
{
public:
class B
{
public:
explicit B() = default;
~B() = default;
private:
double m = std::numeric_limits<double>::max();
};
void f(double d, const B &b = B{}) {}
};
int main()
{
A a{};
a.f(0.);
}
which produces the following similar diagnostic:
t.cpp(15,34): error: default member initializer for 'm' needed within definition of enclosing class 'A' outside of member functions
void f(double d, const B &b = B{}) {}
^
t.cpp(12,20): note: default member initializer declared here
double m = std::numeric_limits<double>::max();
^
Richard Smith indicates this is a bug:
Regarding comment#0: if we want to fix this once-and-for-all, we should use the same technique we use for delayed template parsing: teach Sema to call back into the parser to parse the delayed regions on-demand. Then we would only reject the cases where there's an actual dependency cycle.
Although does not explain why in details.
As of 2021 it's still not fixed, but as a work-around I'm using something like this:
namespace detail {
struct DownloaderHints
{
int32_t numOfMaxEasyHandles = 8;
};
}
class Downloader {
public:
using Hints = details::DownloaderHints;
static Downloader *Create(const Hints &hints = Hints());
};