Syntax differences in variadic template parameter pack forwarding

巧了我就是萌 提交于 2019-12-23 15:36:39

问题


While working with variadic templates I have come across two different ways of writing a call to std::forward, but I am left wondering what the actual difference between the two syntaxes?

template<typename... T>
void one(T&&... args)
{
    foo(std::forward<T&&...>(args...));
}
template<typename... T>
void two(T&&... args)
{
    foo(std::forward<T&&>(args)...);
}

According to my compilers these are both valid syntax, and in most cases the compiler does not complain. But I have found some cases where one or the other is correct but the compiler does not say why in detail.

Is one more correct that the other?
Do they serve different purposes?


回答1:


The ... placement tells the compiler where to expand the pack, once for each element in the thing before it (hard to phrase easily but I'll illustrate below).

Let's consider a pack T = {int, double, char} and args = {1, 2.0, '3'}

Your first example (one) will expand T inside of the <> and then args inside of the () so it becomes

foo(std::forward<T&&...>(args...));  // becomes:
foo(std::forward<int&&, double&&, char&&>(1, 2.0, '3'));

This is not how std::forward works since it only expects one argument. Your second example (two) says to expand the whole call to std::forward once for each item in the packs, so it becomes

foo(std::forward<T&&>(args)...);  // becomes:
foo(std::forward<int&&>(1), std::forward<double&&>(2.0),std::forward<char&&>('3'));

As for why these both compiled fine, the result is identical if you called with only one argument. If you never called it at all then it wouldn't be instantiated.



来源:https://stackoverflow.com/questions/41071181/syntax-differences-in-variadic-template-parameter-pack-forwarding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!