【问题标题】:Can C++17's "template argument deduction" for class templates deduce local types?C++17对类模板的“模板参数推导”可以推导出局部类型吗?
【发布时间】:2016-10-07 12:02:38
【问题描述】:

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当前实现该功能的缺陷吗?

【问题讨论】:

  • 看起来您已经找到并评论了错误报告。

标签: c++ templates gcc c++17 template-argument-deduction


【解决方案1】:

这是当前实现中的一个错误:77890NEW 表示有效性,而不是在 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 的类型。这应该都有效。

猜你喜欢
  • 2019-12-25
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多