我看到 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(使用前将#替换为@)