Cae*_*sar 8 c++ templates type-conversion implicit-conversion
class A
{
struct B{};
public:
static void test(A::B){}
};
struct C
{
template<class T>
operator T()
{
return T();
}
};
int main()
{
A::test(C());
}
Run Code Online (Sandbox Code Playgroud)
此代码适用于clang 3.7,gcc 5.1和vc ++ 14.2.
2问题,
1.为什么模板推导出的类型是A :: B?(太聪明了!)
据我所知,模板通过return语句而不是参数来推断类型.
但是我发现了一些对N4606 12.3.2感兴趣的东西A conversion function template shall not have a deduced return type (7.1.7.4).(但是,我找不到关于此的更多信息,因为7.1.7.4太难理解了.)
2.为什么转换函数模板可以访问A :: B?
谢谢.
- 为什么模板可以推导出类型是A::B?(这么聪明!)
由于test()需要 an A::B,您需要一种将 a 转换C为 an 的方法A::B。我们可以尝试通过转换函数进行初始化,我们在[over.match.conv]中有:
S考虑了 及其基类的转换函数。那些未隐藏在S并产生类型T或可T通过标准转换序列 (13.3.3.1.1) 转换为类型的类型中的非显式转换函数是候选函数。
我们根据[temp.conv]进行模板推导:
模板参数推导是通过将转换函数模板的返回类型(称为 P)与转换结果所需的类型(称为 A;参见 8.6、13.3.1.5 和 13.3.1.6)来完成的。确定该类型)如 14.8.2.5 中所述。
基本上,我们将Tin推导template <class T> operator T()为A::B。这是一个格式良好的转换序列,也是唯一可行的转换序列,所以这就是发生的情况。
您引用的有关“推导的返回类型”的行引用了auto或decltype在返回类型中。这不会发生在这里。
- 为什么转换函数模板可以访问A::B?
访问规则严格与名称有关。名称且只有名称是 私有的 。但我们不是访问名称,而是直接推导类型。BA
B的构造函数是公共的,因此转换函数的主体也是格式良好的,因此有关代码的所有内容都是格式良好的。