通过转换运算符进行模板参数类型推导

2023-12-22

我看到 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 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#349,由开发者打开EDG C++ 前端 https://www.edg.com/index.php?location=c_frontend(这显然推断出int, not const int):

我们在执行时遇到了有关资格转换的问题 转换函数的模板参数推导。

问题是:转换函数中T的类型是什么 通过这个例子调用? T 是“int”还是“const int”?

如果 T 为“int”,则 A 类中的转换函数有效,而 A 类中的转换函数有效 B 类失败(因为返回表达式无法转换为 函数的返回类型)。如果 T 是“const int”,则 A 失败且 B 作品。

因为资格转换是对结果进行的 转换函数,我认为将 T 推导为 const int 没有任何好处。

另外,我认为A类中的代码出现的可能性比 B 类中的代码。如果该类的作者计划 返回指向 const 实体的指针,我希望该函数能够 已在返回类型中写入 const。

因此,我认为正确的结果应该是 T 是 int。

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 中不存在!),并且可能被编译器开发人员忽略了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过转换运算符进行模板参数类型推导 的相关文章

随机推荐