【发布时间】:2026-01-23 13:25:01
【问题描述】:
我能够在 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';
}
}
所以我的第一个问题是,为什么非模板参数在参数包后不起作用?我做错了什么还是语言禁止这样做?
其次,有什么方法可以得到我想要做的语法吗?我过度简化了我的示例,但在我的真实代码中,callback 参数实际上是std::function<...>。这个想法是我可以订阅一些“事件ID”,最后定义回调。最后有回调更好的可读性和样式。示例:
SubscribeMultiple(EventOne, EventTwo, EventThree, [] {
// Implement callback code here when any of the above
// three events are fired.
});
如果我必须在前面有回调,恕我直言,它的可读性较差。所以我愿意尝试任何解决方法来获得我想要的语法和结构。提前致谢。
【问题讨论】:
-
我认为编译器无法确定参数包的结束位置,因为它的评估方式。如果我没记错的话,这家伙解释得很好:youtu.be/…
-
谢谢@keith。任何文本版本?
-
cppcon 2016 的幻灯片都在官方 github 页面github.com/CppCon/CppCon2016 上。 2016 年有一个关于可变参数的演讲 - 也值得一看。
-
P.S.如果您首先想要可变参数,请将它们包装在一个类中!然后,您至少可以为额外的两个大括号执行 SubscribeMultiple2({blah, blah,...}, callback)。