tyllurius
tyllurius

Reputation: 13

Initialization of const data members per constructor member-initializer list, error: no matching function for call

I have following class:

Foo.h

class Foo {
public:
  struct Bus {
    SPIClass *spi;
    const uint8_t pin;
  };

  constexpr Foo(SPIClass *spi, uint8_t csPin) :
      _bus({.spi{spi}, .pin{csPin}}) {}

protected:
  const Bus _bus;
  };

Because of the const member _bus I initialized them using an initializer list in the constructor. But somehow it can't be recognized and it throws following compile errors:

error: no matching function for call to 'Foo::Bus::Bus(<brace-enclosed initializer list>)'
       _bus({.spi{spi}, .pin{csPin}}) {}
                                    ^
note: candidate: 'constexpr Foo::Bus::Bus(const TMC::Motionctrl::Bus&)'
   struct Bus {
          ^~~
note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const Foo::Bus&'
note: candidate: 'constexpr Foo::Bus::Bus(Foo::Bus&&)'
note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'Foo::Bus&&'
error: member 'Foo::_bus' must be initialized by mem-initializer in 'constexpr' constructor
       _bus({.spi{spi}, .pin{csPin}}) {}                             
                                       ^

I guess the second error is because the initialization fails, but I can't find the error. I'm using GCC (GNU Arm Embedded toolchain), build command parameter are

\packages\STM32\tools\arm-none-eabi-gcc\8.2.1-1.7/bin/arm-none-eabi-g++" -mcpu=cortex-m3 -mthumb "@E:\xxx\Release/sketch/build_opt.h" -c -Os -Wall -Wextra -std=gnu++14 -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -fno-use-cxa-atexit -MMD "-

Thx!

Upvotes: 1

Views: 141

Answers (1)

Artyer
Artyer

Reputation: 40791

The GNU extension for designated initializers only supported the .designator = arg form, not the .designator{arg} form which was introduced in C++20. In later versions of gcc, the braced initializer form is also accepted as a gcc extension.

The fix is simply to not use the extension or use an equals initializer:

_bus({.spi = spi, .pin = csPin})  // GNU extension or C++20
_bus{spi, csPin}  // C++11

Upvotes: 1

Related Questions