模板参数类型通过转换操作员扣除

Template argument type deduction by conversion operator

本文关键字:转换 操作员 参数 类型      更新时间:2023-10-16

我在C 11标准(N3337,14.8.2.3/7)中看到示例

struct A {
template <class T> operator T***();
};
A a;
const int * const * const * p1 = a; // T is deduced as int, not const int

并尝试由不同的编译器复制它。我通过在转换函数中添加用T型声明来改变示例

struct A {
    template <class T> operator T***()
    {
        T t;  //if T==const int, then it is error (uninitialized const)
        return nullptr;
    }
};
A a;
const int * const * const * p1 = a;
int main(){}

所有编译器(VS2014,GCC 5.1.0和Clang 3.5.1)在声明" T"的声明中给出了错误,这意味着将t推导为const int。这是为什么?是某种扩展吗?

CWG问题#349 覆盖,由EDG C 前端的开发人员打开(显然是DEWUC int,而不是const int):

我们遇到了有关资格转换的问题 转换功能的模板参数扣除。

问题是:转换功能中T的类型是什么 通过此示例打电话?t" int"或" const int"?

如果t是" int",则A类作品中的转换功能,而在 B级失败(因为返回表达式无法转换为 函数的返回类型)。如果t是" const int",则a失败和b 作品。

因为资格转换是根据 转换功能,我认为将t推断为const int。

没有好处

此外,我认为A类中的代码比 如果班级的作者正在计划 将指针返回到const实体,我希望该功能 已在返回类型中使用const编写。

因此,我相信正确的结果应该是t。

struct A {
  template <class T> operator T***() {
      int*** p = 0;
      return p;
  }
};
struct B {
  template <class T> operator T***() {
      const int*** p = 0;
      return p;
  }
};
int main()
{
  A a;
  const int * const * const * p1 = a;
  B b;
  const int * const * const * p2 = b;
}

我们刚刚实施了此功能,并在委员会的澄清中进行了澄清,我们将t推定为int。 G 和Sun编译器似乎将T推论为const int。

这仅使引用的段落成立(C 03!),并且大概被编译器开发人员忽略了。