当前位置: 首页 > 知识库问答 >
问题:

“......”在变量模板的上下文中,令牌的规则是什么?

东门城
2023-03-14

在C 11中,有如下可变模板:

template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args )
{
    return unique_ptr<T>(new T(std::forward<Args>(args)...));
}

这里有一些奇怪的地方:表达式std::forward

另外:在函数实现中,省略号()位于兴趣表达的末尾。在模板参数列表和参数列表中省略省略是有原因的吗?


共有2个答案

朱宇航
2023-03-14

以下内容摘自Andrei Alexandresu在GoingNative 2012上的演讲“变量模板是有趣的”。我可以推荐它对变量模板的一个很好的介绍。

有两件事可以做一个可变的包。可以应用sizeof。。。(vs)获取元素数量并展开它。

Use            Expansion

Ts...          T1, ..., Tn
Ts&&...        T1&&, ..., Tn&&
x<Ts,Y>::z...  x<T1,Y>::z, ..., x<Tn,Y>::z
x<Ts&,Us>...   x<T1&,U1>, ..., x<Tn&,Un>
func(5,vs)...  func(5,v1), ..., func(5,vn)

扩张向内向外进行。当以锁步展开两个列表时,它们必须具有相同的大小。

gun(A<Ts...>::hun(vs)...);

展开A的模板参数列表中的所有Ts,然后函数hun用allvs展开。

gun(A<Ts...>::hun(vs...));

A的模板参数列表中的所有Ts和所有vs展开为hun的函数参数

gun(A<Ts>::hun(vs)...);

使用锁定步骤中的Tsvs展开函数hun

Ts不是类型,vs不是值!它们是类型/值列表的别名。任一列表都可能为空。两者都只服从特定的行动。所以以下是不可能的:

typedef Ts MyList;  // error!
Ts var;             // error!
auto copy = vs;     // error!
template <typename... Ts>
void fun(Ts... vs)
any a[] = { vs... };
template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { /**/ };
// Inside struct D
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}
std::map<Ts...> m;

只有当参数可能匹配时才会编译。

template <class... Ts> void fun(Ts... vs) {
    auto g = [&vs...] { return gun(vs...); }
    g();
}
struct [[ Ts... ]] IAmFromTheFuture {};

它在规范中,但是还没有可以表示为类型的属性。

归俊
2023-03-14

在变量模板的上下文中,省略号...用于解压模板参数包,如果它出现在表达式的右侧(暂时调用此表达式模式),或者如果它出现在左侧,则为包参数名字的一面:

...thing  // pack   : appears as template arguments
thing...  // unpack : appears when consuming the arguments

规则是,左侧的任何模式 重复-未打包的模式(现在称为表达式)用逗号分隔

通过一些例子可以更好地理解这一点。假设您有此函数模板:

template<typename ...T> //pack
void f(T ... args)      //pack
{
   // here are unpack patterns

   g( args... );        //pattern = args
   h( x(args)... );     //pattern = x(args)
   m( y(args...) );     //pattern = args (as argument to y())
   n( z<T>(args)... );  //pattern = z<T>(args)
}

现在,如果我调用这个函数传递T作为{int, char,短},那么每个函数调用都扩展为:

g( arg0, arg1, arg2 );           
h( x(arg0), x(arg1), x(arg2) );
m( y(arg0, arg1, arg2) );
n( z<int>(arg0), z<char>(arg1), z<short>(arg2) );

在您发布的代码中,std::forward遵循n()函数调用所示的第四种模式。

请注意x(args) y(args…) 以上!

您可以使用将数组初始化为:

struct data_info
{
     boost::any  data;
     std::size_t type_size;
};

std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}

其扩展为:

std::vector<data_info> v 
{ 
   {arg0, sizeof(int)},
   {arg1, sizeof(char)},
   {arg2, sizeof(short)}
};

我刚刚意识到一个模式甚至可以包括访问说明符,如Public,如以下示例所示:

template<typename ... Mixins>
struct mixture : public Mixins ...  //pattern = public Mixins
{
    //code
};

在本例中,模式展开为:

struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN  

也就是说,mixed从所有基类公开派生。

希望有帮助。

 类似资料:
  • TLDR:这是一个关于从及其相应的返回的URL的问题。它询问的主要作用和功能是什么,以及是否需要根据安全规则公开可用的文件。 null null null null

  • template module在Ansible中非常常用,而它在使用的时候又没有显示的指定template文件中的值,所以有时候用户会对template文件中使用的变量感到困惑,所以在这里又重新强调下。 template变量的定义 在playbook中定义的变量,可以直接在template中使用,同时facts变量也可以直接在template中使用,当然也包含在inventory里面定义的host

  • 我试图在变量函数模板上使用'decltype'来获取其返回值类型,然后使用它来定义成员变量。但我一直在犯这样的错误: 基本上,decltype失败并将声明为int,而不是推断的返回类型。 它的工作原理是当我提供的所有参数的值,但这不是我要找的行为。因为我不知道该函数有多少参数,所以它必须保持为可变模板函数。 我计划如何使用类模板的示例: 如果我没有任何成员变量,并使用作为: 它编译,因此我相信能够

  • 问题内容: 我试图将值放入“标题”模板中,例如标题和导航链接,但无法访问我从包含的模板发送到主模板的变量。 渲染模板: index.html模板: header.html模板: 显然,它不会那样工作。 也许有一种方法可以解析/获取模板并将变量放入其中,而无需将整个头文件放入代码中?然后,我可以将该模板作为变量发送到我的主模板。但这似乎并不是最好的方法。 问题答案: 您可以在调用模板时将上下文传递给

  • 变量规则 系统默认的变量规则设置是\w+,只会匹配字母、数字和下划线字符,并不会匹配特殊符号和中文,需要定义变量规则或者调整默认变量规则。 V5.1.14+版本开始,可以在app.php配置文件中自定义默认的变量规则: 'default_route_pattern' => '[\w\-]+', 支持在规则路由中为变量用正则的方式指定变量规则,弥补了动态变量无法限制具体的类型问题,并且支持全局规则

  • 如何添加一个“全局”变量(如用户名),以便在模板上下文中使用? 目前,我正在将这些显式设置到我的TemplateController中的每个ModelAndView对象。