c – 验证GCC中的错误
我想验证以下是GCC中的错误,而不是我对C的理解.请考虑以下代码:
struct A { struct B { template< typename U > U as() const { return U(); } }; B operator[]( int ) const { return B(); } }; template< typename T > struct as { template< typename U > static T call( const U& u ) { return u[ 0 ].as< T >(); // accepted by Clang 3.2,rejected by GCC 4.7 // return u[ 0 ].template as< T >(); // does not help and is IMHO not needed // return u[ 0 ].A::B::as< T >(); // accepted by GCC 4.7 } }; int main() { as< int >::call( A() ); } IMHO的代码应该很好,它被Clang 3.2接受,但不是由GCC 4.7接受(4.4和4.6也失败,基本相同的错误,但是4.4产生一个稍微不同的消息).这是我的shell的输出: $clang++-3.2 -O3 -Wall -Wextra -std=c++0x t.cc -o t $g++-4.7 -O3 -Wall -Wextra -std=c++0x t.cc -o t t.cc: In static member function ‘static T as<T>::call(const U&)’: t.cc:17:21: error: invalid use of ‘struct as<T>’ t.cc: In static member function ‘static T as<T>::call(const U&) [with U = A; T = int]’: t.cc:18:4: warning: control reaches end of non-void function [-Wreturn-type] $ 问题:这是GCC中的错误还是我错过了什么? 编辑:我有点困惑:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55576的GCC错误报告在评论#9中表示,评论3中的代码是“有效的”.这是什么意思?看起来像海湾合作委员会的人认为它实际上是一个错误,否则他们已经关闭了? OTOH从@Potatoswatter的答案似乎很清楚,它应该是正确的,我应该向Clang提交一个错误报告(或者是否已经有这样的错误报告?) 请注意,我犹豫,将答案标记为接受,直到上述澄清.既然这两个答案都是有帮助的(一个解释一个解决方案),我给了一个upvote. 奖金问题:由于我没有非叙述性的代码,我想知道别人的感受.我试图创建一个SCCEE,消除所有的分心,并集中在技术问题上.这就是我更喜欢考虑这些事情.那是错的吗 另外@EdHeal:为什么代码容易发生灾难? (你不认为这是真实世界的代码,对吗?) 编辑2:谢谢大卫,刚刚注意到你的编辑.我会将您的答案标示为现在接受,我也看到您对GCC错误报告发表了评论.我认为这个问题的要点得到了回答,海湾合作委员会再次提醒.感谢大家. 解决方法
这是语言的一个棘手的角落. GCC正在应用C 03§3.4.5/ 1的规则:
请注意,此过程是无用的,因为已经需要使用template关键字来消除<令牌,因为子表达式u [0]的类型取决于模板参数. 以这种方式执行此操作的原因是为了简化解析,只要在嵌套名称限定符中使用template-id,例如u [0] .as< T> :: bar.baz其中bar是基类的typedef. C 11删除了三个项目符号,简化了过程
所以这是一个bug,而不是像以前说过的一个bug.名称查找角箱需要删除. 此外,看起来这个怪癖可以被利用来允许单个模板表达式交替地引用一个类或一个函数.不知道这是否有用,但在C11中却是新的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |