参数打包后的参数

时间:2017-02-03 14:48:15

标签: c++ variadic-templates

我能够在SO上找到one question似乎在问我相同或类似的问题,但没有答案: - (

我想在参数包之后放置一个非模板参数。我不太熟悉可变参数模板/参数包的C ++标准规范,但我的常识假设告诉我,传递给函数的最右边的参数将首先填充到放置参数中,然后其余的填充到参数包。但是,我无法将我的测试代码用于g ++或clang ++。示例代码如下。

#include <vector>
#include <iostream>

int Subscribe(int channel, int callback)
{
    return channel;
}

// This one works fine...
template<typename... T>
std::vector<int> SubscribeMultiple1(int callback, T&&... channels)
{
    return {
        Subscribe(std::forward<T>(channels), std::move(callback))...
    };
}

// This one does not work; all I did was move `int callback` after the parameter pack.
template<typename... T>
std::vector<int> SubscribeMultiple2(T&&... channels, int callback)
{
    return {
        Subscribe(std::forward<T>(channels), std::move(callback))...
    };
}

int main()
{
    auto subs = SubscribeMultiple2(1, 2, 3);

    for (auto sub : subs)
    {
        std::cout << "Sub: " << sub << '\n';
    }
}

Live Sample

所以我的第一个问题是,为什么非模板参数在参数包之后不起作用?我做错了什么还是被语言禁止了?

其次,有没有办法获得我正在尝试的语法?我过度简化了我的示例,但在我的实际代码中,callback参数实际上是std::function<...>。我的想法是我可以订阅许多“事件ID”,并在最后定义回调。最后回调对于可读性和风格更好。例如:

SubscribeMultiple(EventOne, EventTwo, EventThree, [] {
    // Implement callback code here when any of the above
    // three events are fired.
});

如果我必须在前面进行回调,那么它的可读性会降低。所以我愿意尝试任何解决方法来获得我的目标语法和结构。提前谢谢。

1 个答案:

答案 0 :(得分:4)

  

我做错了什么还是被语言禁止了?

只有在包是最后一个参数时才会扣除参数包。

[temp.deduct.type]/5.7

  

未推断的上下文是:

     
      
  • [...]
  •   
  • 不在 parameter-declaration-list 末尾出现的函数参数包。
  •   

这是标准C ++的正常行为。

  

有没有办法获得我试图做的语法?

使用第一种语法作为解决方法:

   template<typename... T>
   std::vector<int> SubscribeMultiple1(int callback, T&&... channels)