[英]template function specialization using variadic arguments
我有一个 class ,它采用可变数量的 arguments (不包括参数),但是当我尝试将结构作为其构造函数的参数传递时,出现编译时错误:
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 });
这是我的 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),...);
}
这是实现文件:
/*ioPin.cpp*/
#include "ioPin.hh"
ioPin::ioPin()
{
init();
}
这是主要的:
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;
}
我尝试向 ioPin.hh 文件添加模板专业化:
template<>
ioPin::ioPin<ioPinParams>(ioPinParams params)
{
}
但是错误仍然完全相同。
如果我从构造函数中删除显式说明符,则程序编译但方法
bool init(const ioPinParams &):
永远不会被调用。
作为最后的手段,我想到了重载构造函数的愚蠢想法,例如:
explicit ioPin(const ioPinParams &);
但后来我得到了明显的:模棱两可的错误:
error: call of overloaded 'ioPin(<brace-enclosed initializer list>)' is ambiguous
11 | t::A, .mode = gpioMode::output, .state = pinState::high });
^
我真的很感激这方面的帮助。 我不知道我错过了什么。
{.port = gpioPort::A, .mode = gpioMode::output, .state = pinState::high }
这是一个带括号的初始化列表,具有某种未指定的类型。 它需要绑定到指定的类型。 这需要以某种方式指定:“您好,我是 class X
或 class Y
”。
如果这作为参数传递给声明为X
或Y
的某些 function ,那么一切都会弄清楚。
不幸的是,这是您遭受 C++ 编译器必须处理的唯一事情:
template<class ...Args>
explicit ioPin(Args ...args);
这就是参数的含义。 这里的Args
也是一些神秘的、未指定的类型,它被推断为传入的实际 object 的类型。
但是传入的也是一些想要弄清楚它的类型的东西。 TLDR 版本:大括号初始化列表不能用于推导模板参数。
您将明确指定这种神秘类型是什么:
ioPin e( ioPinParams{.port = gpioPort::A, .mode = gpioMode::output, .state = pinState::high });
这解决了这个史酷比之谜。 一个 ioPinParams 参数被传递到构造函数中,这就是模板参数的推导,然后通过重载解析转发到正确的初始化 function。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.