考虑以下类型定义的模拟:
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
(偏移的性质并不重要)。它还提供了从Foo
到FooView
offset = 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}; }
但无济于事。编译器仍会抛出相同的错误。
答案 0 :(得分:3)
类模板参数推导仅适用于certain situations,它们都需要使用实际的类模板占位符。 arg
不会触发扣除,只有cls(arg)
会扣除。
yada(foo)
只是遵循重载决策的常规规则,由于foo
不是FooView
(模板推断不考虑转换),因此重载解析失败。
yada(FooView(foo))
执行类模板参数演绎,因为您要求它。这始终是一个明确的按需功能。