W.F*_*.F. 32 c++ templates local-class generic-lambda c++14
据我所知 - 泛型lambda被转换为具有模板化的局部范围结构的对象operator()
.这使得通用lambda非常强大且易于使用的工具.另一方面,可以创建嵌套到函数中的结构,但是当结构具有模板化成员时,例如:
#include <iostream>
int main() {
struct inner {
template <class T>
void operator()(T &&i) { }
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者自己模仿:
int main() {
template <class T>
struct inner {
void operator()(T &&i) { }
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器似乎有编译它的问题:
Run Code Online (Sandbox Code Playgroud)error: invalid declaration of member template in local class
和
Run Code Online (Sandbox Code Playgroud)error: a template declaration cannot appear at block scope
我认为问题在c ++标准中比在编译器bug中更多.lambdas被允许拥有模板化成员而不是本地结构的原因是什么?
我发现了这个问题,但我认为答案有点过时(即使对于c ++ 11,我也不认为这是真的).
Col*_*mbo 27
这是核心问题728,它是在通用lambda之前提交的.
您提到了通用lambdas,它们与具有相应成员的本地类相同template operator()
.但是,它们实际上并非如此,并且差异与实施特征有关.考虑
template <typename T>
class X {
template <typename>
void foo() {
T t;
}
};
Run Code Online (Sandbox Code Playgroud)
和
template <typename T>
auto bar() {
return [] (auto) {T t;};
};
Run Code Online (Sandbox Code Playgroud)
<void>
在第一种情况下实例化这些模板将是正常的,但在第二种情况下是不正确的.为什么在第一种情况下罚款?foo
不需要为每个特定实例化T
,而只需要其中一个(这将是[temp.res] /(8.1)).
为什么在第二种情况下形成不良?通用lambda的主体使用提供的模板参数进行实例化 - 部分 - .这种部分实例化的原因是......
...处理函数定义时使用的词法范围基本上是暂时的,这意味着很难支持延迟函数模板定义某些部分的实例化.
(Richard Smith)我们必须实例化足够的本地"模板",使其独立于本地上下文(包括封闭函数模板的模板参数).
这也与[expr.prim.lambda]/13的基本原理有关 ,它要求一个实体被lambda隐式捕获,如果它......
在潜在评估表达式([basic.def.odr])中命名实体,其中封闭的full-expression依赖于在lambda-expression的到达范围内声明的泛型lambda参数.
也就是说,如果我有一个像lambda一样的[=] (auto x) {return (typename decltype(x)::type)a;}
地方,a
来自封闭函数的某个块范围变量,无论是否x
成员typedef是否void
存在,强制转换将导致捕获a
,因为我们必须在不等待的情况下做出决定为了调用lambda.有关此问题的讨论,请参阅有关通用lambdas的原始提议.
底线是完全推迟成员模板的实例化与(至少一个)主要实现所使用的模型不兼容,并且由于这些是预期的语义,因此未引入该特征.
那是这种约束的最初动机吗?它是在1994年1月至5月的某个时间引入的,没有任何论文覆盖它,因此我们只能粗略地了解本文中为什么本地类不应该是模板参数的理由:
类模板和从模板生成的类是全局范围实体,不能引用本地范围实体.
也许那时候,人们想要亲吻.
归档时间: |
|
查看次数: |
1214 次 |
最近记录: |