【问题标题】:Template argument type deduction by conversion operator通过转换运算符推导模板参数类型
【发布时间】:2015-07-22 05:52:06
【问题描述】:

我看到了来自 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。这是为什么?是扩展名吗?

【问题讨论】:

  • 恭喜,您发现了一个编译器错误。 (这不是一个符合标准的扩展;它拒绝根据标准格式正确的代码。)
  • @T.C.就reported吧。太糟糕了 bugzilla 不允许你 ninja-edit 提交!
  • 太棒了。多达 3 个编译器具有相同的错误 :) icc 13.0.1 编译器正常
  • @user3514538 正如我在回答中提到的,EDG 的开发人员提交了缺陷报告。英特尔编译器采用 EDG 前端;这就解释了为什么它是这里唯一符合要求的实现。

标签: c++ templates c++11 operator-overloading type-deduction


【解决方案1】:

这由CWG issue #349 覆盖,由EDG C++ front end 的开发人员打开(显然推断int,而不是const int):

我们在做的时候遇到了一个关于资格转换的问题 转换函数的模板参数推导。

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

如果 T 是“int”,则 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 中不存在!),并且可能被编译器开发人员忽略了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 2020-12-14
    • 1970-01-01
    • 2019-04-17
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多