Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解可变模板函数中的点_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ 理解可变模板函数中的点

C++ 理解可变模板函数中的点,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,假设我有下面的代码。我在很大程度上理解了这一点 template <class ...Args> //---> Statement A void foo_imp(const Args&... args) //---> Statement B { std::vector<int> vec = {args...}; //---> Statement C } 建议…是变量类型,Args是变量名(这很好)

假设我有下面的代码。我在很大程度上理解了这一点

template <class ...Args>               //---> Statement A
void foo_imp(const Args&... args)      //---> Statement B
{
    std::vector<int> vec = {args...};  //---> Statement C
}
建议
是变量类型,Args是变量名(这很好)

声明B,如下所示

template <class ...Args>  
void foo_imp(const Args&... args) 
在我看来,这似乎是Args类型,而Args是模板类型,但是在
Args
之后添加
..
会让我感到困惑吗

然后将值赋给vector会让人更加困惑

 std::vector<int> vec = { args... };
std::vector vec={args…};
为什么在args后面有

关于如何记住上面的代码以便对我有意义,有什么想法吗?

Args
声明为可变参数包,其中每个参数的(元)类型为
class
。为了便于解释,我们假设这可以被认为类似于:

<class Args1, class Args2, class Args3, etc.>
相当于

void foo_imp(Args1, Args2, Args3, etc.) 
void foo_imp(const Args1&, const Args2&, const Args3&, etc.)  
使用参数包的值将对象向左展开。所以在你的实际例子中

void foo_imp(const Args&...)    
相当于

void foo_imp(Args1, Args2, Args3, etc.) 
void foo_imp(const Args1&, const Args2&, const Args3&, etc.)  
现在是时候放弃模板参数包作为固定大小的类型列表的想法了;实际上,它的长度是由调用时提供的参数数量决定的

“但是我们在调用时不提供任何模板参数!?!”我听到你说。这是因为
foo_imp
是一个函数,其模板参数是在其正常参数的基础上推导出来的。这意味着
(常量Args1&,常量Args2&,常量Args3&)列表的长度由函数调用确定,每个
ArgsN
类型由函数模板类型推断的常规规则确定


现在转到
args
。与
Args
类似,
Args
是一个可变参数包,因此在使用时必须进行扩展

std::vector<int> vec = {args...};
如果这样一个扩展表达式出现在参数列表中,它可以被可变参数包变量捕获。在这种情况下,如果表达式不包含任何可变参数包,则会释放参数列表以获取任意数量的参数

template<typename ...Baz> => Baz is a variable length variadic parameter pack of `typename`s
void bar(Baz ...baz)      => baz is a parameter pack of `Baz`s
void bar(Baz &&...baz)    => baz is a parameter pack of `Baz&&`s
template=>Baz是'typename'的可变长度可变参数包
void bar(Baz…Baz)=>Baz是'Baz'的参数包
void bar(Baz&&…Baz)=>Baz是'Baz&&'的参数包
std::forward<Args...>(args...)
//expands as:
std::forward<Args1, Args2, Args3, etc.>(args1, args2, args3, etc)    
//Foo and bar are variadic parameter packs
Foo...                     => Foo1, Foo2, Foo3, etc
std::vector<Foo>...        => std::vector<Foo1>, std::vector<Foo2>, std::vector<Foo3>, etc.
std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc)
&bar...                    => &bar1, &bar2, &bar3, etc
template<typename ...Baz> => Baz is a variable length variadic parameter pack of `typename`s
void bar(Baz ...baz)      => baz is a parameter pack of `Baz`s
void bar(Baz &&...baz)    => baz is a parameter pack of `Baz&&`s