在可变参数模板中使用标准::p花边

Using std::placeholders in variadic templates

本文关键字:标准 花边 变参 参数      更新时间:2023-10-16

我在采用可变参数模板的函数中使用std::placeholders时遇到困难。我开始认为我不需要使用可变参数模板,但我已经尝试了很长时间,我在杂草中思考,需要一个外观焕然一新的人。

以下模板化函数采用常规模板化参数,然后采用可变参数。它导致编译器错误:

registerEvent<UpdaterComponent, std::_Ph<1>>(EVT_INIT, &UpdaterComponent::initialise, std::placeholders::_1); 

编译器错误:

错误 1 错误 C2664: 'Status Component::registerEvent>(const int &,Status UpdaterComponent::* (__cdecl )(const EventArgs &),std::_Ph<1>)' : 无法将参数 2 从"Status (__thiscall UpdaterComponent:: )(const EventArgs &)

" 转换为 'Status UpdaterComponent::* (__cdecl *)(const EventArgs &)'

这里到底出了什么问题,我该如何解决这个编译器错误?

// In class Component
template<typename T, typename... Params>
Status registerEvent(int evtId, Status T::*func(const EventArgs& evtArgs), Params...)
{
    ... irrelevant code removed for brevity
    auto res = std::bind(func, this, Params...);
    ... irrelevant code removed for brevity
}

// Usage
class UpdaterComponent : public Component
{
public:
    UpdaterComponent()
    {
        registerEvent<UpdaterComponent, std::_Ph<1>>(EVT_INIT, &UpdaterComponent::initialise, std::placeholders::_1);
    }
};

主要问题是你缺少括号:

template<typename T, typename... Params>
Status registerEvent(int evtId, Status (T::*func)(const EventArgs& evtArgs), Params...)
                                      ^^^       ^^^

所以你最终会弄错func的类型。

修复此问题后,为什么要显式提供所有模板参数?这就是模板扣除的目的!当你发现自己在打std::_Ph,不要。这就足够了:

registerEvent(EVT_INIT, &UpdaterComponent::initialise, std::placeholders::_1);