在可变参数模板中使用std :: placeholders

时间:2016-03-03 02:39:19

标签: c++ templates c++11 variadic-templates

我在使用可变参数模板的函数中使用std::placeholders时遇到困难。我开始认为我不需要使用可变参数模板,但我已经尝试了这么久,我在杂草中思考并需要一个看起来很新鲜的人。

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

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

编译错误:

  

错误1错误C2664:&#39; Status Component :: registerEvent&gt;(const int&amp;,Status UpdaterComponent :: *(__ cdecl )(const EventArgs&amp;),std :: _ Ph&lt; 1&gt;) &#39; :无法转换参数2来自&#39;状态(__thiscall UpdaterComponent :: )(const EventArgs&amp;)&#39; to&#39; Status UpdaterComponent :: *(__ cdecl *)(const EventArgs&amp;)&#39;

这里究竟出现了什么问题以及如何修复此编译器错误?

// 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);
    }
};

1 个答案:

答案 0 :(得分:2)

主要问题是你缺少括号:

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);