转换运算符的模板参数类型推导

时间:2015-05-11 16:08:18

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

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

1 个答案:

答案 0 :(得分:9)

CWG issue #349EDG C++ front end的开发者打开(显然推断int,而不是const int

  

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

     

问题是:转换函数中的T类型是什么   这个例子叫做?是T&#34; int&#34;或&#34; const int&#34;?

     

如果T是&#34; int&#34;,则A类中的转换函数起作用   B类失败(因为返回表达式无法转换为   函数的返回类型)。如果T是&#34; const int&#34;,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中不存在!),并且可能被编译器开发人员忽略了。