功能中的参数打包后的参数

voi*_*ter 1 c++ variadic-templates

我能够在SO 上找到一个问题,似乎在问与我相同或相似的问题,但是没有答案:-(

我想在参数包后放置一个非模板参数。我对可变参数模板/参数包的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';
    }
}
Run Code Online (Sandbox Code Playgroud)

现场样本

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

其次,有什么方法可以获取我要尝试的语法?我简化了示例,但在我的实际代码中,该callback参数实际上是个std::function<...>。我的想法是我可以订阅许多“事件ID”,并且在最后定义回调。在结尾加上回调会更好地提高可读性和样式。例:

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

如果我必须将回调放在最前面,恕我直言。因此,我愿意尝试任何变通方法以获取我想要的语法和结构。提前致谢。

rus*_*tyx 5

我做错什么了吗?还是语言禁止这样做?

仅在参数包是最后一个参数时才进行参数包的推导。

[temp.deduct.type] /5.7

非推论上下文是:

  • [...]
  • parameter-declaration-list末尾没有出现的功能参数包。

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

有什么方法可以获取我要尝试的语法?

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

   template<typename... T>
   std::vector<int> SubscribeMultiple1(int callback, T&&... channels)
Run Code Online (Sandbox Code Playgroud)