【问题标题】:Use deductions guides in implicit argument conversion在隐式参数转换中使用推导指南
【发布时间】:2018-03-08 14:37:22
【问题描述】:

考虑以下类型定义的模拟:

template<typename T> struct Foo {};

template<typename T, size_t offset>
struct FooView {
    FooView(const Foo<T>&) {}
};
template<typename T> FooView(const Foo<T>&) -> FooView<T, 0>;

template<typename T, size_t s>
void yada(FooView<T, s> arg) {}

正如你所看到的,我们有一个类型Foo,这里表示一个事物的集合T和一个类型FooView,它应该表示一个Foo的视图,以及一些偏移量s(自然偏移量不是那么重要)。它还提供了从FooFooViewoffset = 0 的演绎指南。

现在,考虑如何使用它:

Foo<float> foo;
// yada(foo); // <-- error: no matching function for call to 'yada'
yada(FooView{foo});

我原以为隐式构造函数与推导指南配对足以使注释调用工作,但实际上我必须键入转换。我能不能让它隐式转换?

我尝试在Foo 中引入一个隐式转换运算符,如下所示:

operator FooView<T, 0>() { return FooView{*this}; }

但无济于事。编译器仍然会抛出同样的错误。

【问题讨论】:

  • 神螺栓链接godbolt.org/g/7BBUU8
  • 可能是代码有错别字? Bar 代替 FooView,也许?
  • @ArdaAytekin 是的,忘了从 Godbolt 复制回来
  • 模板参数推导不考虑可能的转换。 foo 不是 "FooView" 所以模板参数推导无法推导出 yada 的模板参数

标签: c++ c++17 implicit-conversion


【解决方案1】:

类模板参数推导仅适用于certain situations,都需要使用实际的类模板占位符。 arg 不会触发扣减,只有cls(arg) 会触发。

yada(foo)只是遵循重载解析的正常规则,由于foo不是FooView(模板推导不考虑转换),重载解析失败。

yada(FooView(foo)) 进行类模板参数推导因为你要求它。这始终是一项明确的按需功能。

【讨论】:

  • 然后我将说明琐碎的函数重载。有点乏味,但仍然比每次使用都要好。
  • @WorldSEnder 如果你想要转换,你总是需要把它们拼出来。模板匹配,它们不转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
相关资源
最近更新 更多