繁体   English   中英

使用可变参数 arguments 的模板 function 特化

[英]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 ”。

如果这作为参数传递给声明为XY的某些 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM