P0091R3 ("Template argument deduction for class templates")最近被添加到gcc
trunk,可以在wandbox上进行测试。
我想到的是使用它来实现的可能性 “范围保护”只需几行代码:
scope_guard _([]{ cout << "hi!\n" });
我试过implementing it on wandbox ...
template <typename TF>
struct scope_guard : TF
{
scope_guard(TF f) : TF{f} { }
~scope_guard() { (*this)(); }
};
int main()
{
scope_guard _{[]{}};
}
...但编译失败,出现以下错误:
prog.cc:6:5: error: 'scope_guard(TF)-> scope_guard<TF> [with TF = main()::<lambda()>]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive]
scope_guard(TF f) : TF{std::move(f)} { }
^~~~~~~~~~~
然后我尝试了using a non-lambda local type,并得到了同样的错误。
int main()
{
struct K { void operator()() {} };
scope_guard _{K{}};
}
之后,I tried a non-local type,它按预期工作。
struct K { void operator()() {} };
int main()
{
scope_guard _{K{}};
}
此功能是否以防止推断本地类型的方式设计?
或这是gcc
当前实现该功能的缺陷吗?
答案 0 :(得分:7)
这是当前实现中的一个错误:77890( NEW表示有效性,而不是在7.0中修复的UNCONFIRMED )。能够演绎lambda是原始论文的一个激励性例子,如果它不起作用会很尴尬:
// Virtually impossible to pass a lambda to a template class' constructor without declaring the lambda for_each(vi2.begin(), vi2.end(), Foo<???>([&](int i) { ...}));
for_each(vi.begin(), vi.end(), Foo([&](int i) { ...})); // Now easy instead of virtually impossible
我们可以创建一个非常基本的例子:
template <typename TF>
struct scope_guard
{
scope_guard(TF ) { }
};
int main()
{
scope_guard _([]{});
}
这应该对由函数组成的合成函数集执行重载解析:
template <class TF> scope_guard<TF> synthesized(TF );
template <class TF> scope_guard<TF> synthesized(scope_guard<TF> const& );
template <class TF> scope_guard<TF> synthesized(scope_guard<TF>&& );
应该选择第一个重载并使用该返回类型作为_
的类型,其中TF
是lambda的类型。这应该都有效。