В настоящее время я борюсь с количеством фигурных скобок в списке параметров, даже если я использую C++2a
указанный инициализатор.
У меня есть несколько вложенных структур в качестве примера:
#include <string>
#include <optional>
struct Base
{
std::string name;
};
struct KL: public Base
{
int p1;
int p2;
};
struct FFA: public Base
{
int pp1;
int pp2;
int pp3;
};
struct Spur
{
std::optional< KL > kl;
std::optional< FFA > ffa ;
};
struct Config
{
std::string s;
int i1;
int i2;
Spur spur;
Config(
const std::string& _s,
int _i1,
int _i2,
const Spur& _spur
): s{_s},i1{_i1},i2{_i2},spur{_spur}{}
};
class Signal
{
public:
Signal( const Config& ) {}
};
struct A { int i; };
struct B { std::string s; };
struct X { A a; B b; };
int main()
Spur s1{ .kl= {{ "XYZ", 1,2 }}}; // works! gcc+clang but clang warns "suggest braces around initialization of subobject"
Spur s2{ .kl= { "XYZ", 1,2 }} ; // fails! could not convert '{"XYZ", 1, 2}' from '<brace-enclosed initializer list>' to 'std::optional<KL>'
Spur s3{ { .kl= { "XYZ", 1,2 }}}; // works gcc! clang fails: no matching constructor for initialization of 'std::optional<KL>'
Config c1{ "ABC", 1,2 , {{ .kl=std::nullopt }}}; // works gcc, clang fails no matching constructor for initialization of 'Config'
Config c2{ "ABC", 1,2 , { .kl=std::nullopt }} ; // works for gcc and clang
Signal si1{ {"ABC", 1,2 , {{ .kl = std::nullopt }} }}; // gcc ok, clang fails: no matching constructor for initialization of 'Signal'
Signal si2{ {"CDE", 3,4 , {{ .kl = KL{ "XYZ", 1,2 } }} }}; // gcc ok, clang fails: no matching constructor for initialization of 'Signal'
Signal si3{ {"CDE", 3,4 , {{ .kl = { "XYZ", 1,2 } }} }}; // gcc ok, clang fails: no matching constructor for initialization of 'Signal'
Signal si4{ {"CDE", 3,4 , { .kl = KL{ "XYZ", 1,2 } } }}; // clang & gcc ok
Signal si5{ {"CDE", 3,4 , { .kl = { "XYZ", 1,2 } } }}; // gcc& clang fail: no matching function for call to 'Signal::Signal(<brace-enclosed initializer list>)'
X x{ .b={"Hallo" }};
X x2{ .a={1} };
Мой вопрос:
Когда мне нужен еще один набор скобок для набора параметров в списке инициализатора?
Я уже прочитал Вложенные скобки и обозначенные инициализаторы
Использованные компиляторы:
clang version 6.0.1
и g++ (GCC) 8.2.1
Флаги: -std=c++20
Может кто-нибудь объяснить, какое правило должно быть выполнено, чтобы избавиться от всех ошибок и предупреждений? (clang всегда предупреждает о пропущенных скобках, но я не могу найти, где мне следует установить дополнительные, которые не нарушали gcc для компиляции). Было бы неплохо получить пример, который можно скомпилировать на gcc и clang.