我看到了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。这是为什么?是扩展吗?
答案 0 :(得分:9)
CWG issue #349由EDG 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中不存在!),并且可能被编译器开发人员忽略了。