'struct with default members initializers cannot be inside class and used as default argument
The following code does not compile:
#include <iostream>
struct toto {
struct options final {
bool option1 = false;
bool option2 = false;
};
static void func(const options &opt = {}) {
std::cout << "option1 = " << opt.option1 << std::endl;
std::cout << "option2 = " << opt.option2 << std::endl;
}
};
int main() {
toto::func();
}
I get the following errors:
test-default-member-init.cc:12:42: error: default member initializer for 'option1' needed within definition of enclosing class 'toto' outside of member functions
static void func(const options &opt = {}) {
^
test-default-member-init.cc:8:10: note: default member initializer declared here
bool option1 = false;
^
test-default-member-init.cc:19:14: error: too few arguments to function call, single argument 'opt' was not specified
toto::func();
~~~~~~~~~~ ^
test-default-member-init.cc:12:3: note: 'func' declared here
static void func(const options &opt = {}) {
^
2 errors generated.
But if I move the options struct outside of my enclosing toto struct, it does compile:
#include <iostream>
struct options final {
bool option1 = false;
bool option2 = false;
};
struct toto {
static void func(const options &opt = {}) {
std::cout << "option1 = " << opt.option1 << std::endl;
std::cout << "option2 = " << opt.option2 << std::endl;
}
};
int main() {
toto::func();
}
I'm using clang on OSX, and compile the code snippet this way:
$ clang --version
Apple clang version 12.0.0 (clang-1200.0.32.2)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ c++ -std=c++17 -stdlib=libc++ -o test-default-member-init test-default-member-init.cc
Can someone explain me why the first code snipped it does not compile, and if there is any solution to get it working?
Solution 1:[1]
I had a similar issue, It only happens on XCode. The only workaround that I found is to have 2 functions, one with a parameter and another one without it. Call the second function/constructor from the first one with the default value.
Header
struct CreateEntityParams
{
bool serializable = true;
};
explicit Entity(
EntityId id,
std::string name,
Entity * parent = nullptr
);
explicit Entity(
EntityId id,
std::string name,
CreateEntityParams const params
Entity * parent = nullptr
);
Cpp
Entity::Entity(
EntityId id,
std::string name,
Entity * parent
)
: Entity(id, name, parent, CreateEntityParams {})
{}
Entity::Entity(
EntityId const id,
std::string name,
CreateEntityParams const & params,
Entity * parent
)
: mId(id)
, mName(std::move(name))
, mParent(parent)
, mSerializable(params.serializable)
{}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
