I have a class that takes a variable number of arguments (including no arguments) but when I try to pass a struct as argument for its constructor, I get a compile time error:
error: converting to 'const ioPin' from initializer list would use explicit constructor 'ioPin::ioPin(Args ...) [with Args = {gpioPort, gpioMode, pinState}]'
11 | t::A, .mode = gpioMode::output, .state = pinState::high });
This is my class:
/*ioPin.hh*/
struct ioPinParams
{
gpioPort port{gpioPort::null};
gpioPin pin{gpioPin::null};
gpioMode mode{gpioMode::input};
gpioPUPD pupd{gpioPUPD::disabled};
gpioOutputType oType{gpioOutputType::pushPull};
gpioOutputSpeed oSpeed{gpioOutputSpeed::low};
pinState state{pinState::low};
};
class ioPin
{
private:
bool init();
bool init(const GPIO_TypeDef *);
bool init(const gpioPort &);
bool init(const ioPinParams &);
bool init(const gpioPin &);
bool init(const gpioMode &);
bool init(const gpioPUPD &);
bool init(const gpioOutputType&);
bool init(const gpioOutputSpeed&);
bool init(const pinState &);
public:
explicit ioPin();
template<class ...Args>
explicit ioPin(Args ...args);
~ioPin();
};
template<class ...Args>
ioPin::ioPin(Args ...args)
{
init();
(init(args),...);
}
This is the implementation file:
/*ioPin.cpp*/
#include "ioPin.hh"
ioPin::ioPin()
{
init();
}
This is the main:
ioPin a; /* <--- This instantation works well */
ioPin b(gpioMode::output, gpioPin::_5, pinState::high, gpioPUPD::disabled, GPIOA); /* <--- This instantation works well */
ioPin c(GPIOA, gpioPin::_5, gpioMode::output, pinState::high); /* <--- This instantation works well */
ioPin d(gpioMode::output, gpioPin::_5, pinState::high, gpioPort::A); /* <--- This instantation works well */
ioPin e( {.port = gpioPort::A, .mode = gpioMode::output, .state = pinState::high }); /* <--- Here is where the error arises */
int main(void)
{
while (1)
{
/* code */
}
return 0;
}
I tried adding a template specialization to the ioPin.hh file:
template<>
ioPin::ioPin<ioPinParams>(ioPinParams params)
{
}
But the error remains exactly the same.
If I remove the explicit specifier from the constructor, the program compiles but the method
bool init(const ioPinParams &):
Never gets called.
As the last resort, I though of the dumb idea of overloading the constructor like:
explicit ioPin(const ioPinParams &);
But then I get what is obvious: ambiguous error:
error: call of overloaded 'ioPin(<brace-enclosed initializer list>)' is ambiguous
11 | t::A, .mode = gpioMode::output, .state = pinState::high });
^
I'd really appreciate help on this. I don't know what am I missing.