我想验证以下是 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() );
}
恕我直言,代码应该没问题,它被 Clang 3.2 接受,但不被 GCC 4.7 接受(4.4 和 4.6 也失败,错误基本相同,但 4.4 产生的消息略有不同)。这是我的外壳的输出:
$ 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 中的代码是“有效的”。这到底是什么意思?看起来 GCC 的人认为这实际上是一个错误,否则他们早就关闭了它?OTOH @Potatoswatter 的答案似乎很清楚,它应该是正确的,我应该针对 Clang 提交错误报告(或者是否已经有这样的错误报告?)
请注意,在澄清上述内容之前,我会犹豫将答案标记为已接受。由于这两个答案都已经很有帮助(一个解释,一个解决),我给了两个答案。
奖励问题:由于我对非叙述性代码投了反对票,我想知道其他人的感受。我试图创建一个 SCCEE,它可以消除所有干扰并专注于技术问题。这就是我更喜欢思考这些事情的方式。那是错的吗?
另外,@EdHeal:为什么代码容易发生灾难?(你认为这不是我拥有的真实代码,对吧?)
EDIT2:谢谢,大卫,刚刚注意到你的编辑。我现在会将您的答案标记为已接受,并且我还看到您对 GCC 错误报告发表了评论。我认为这个问题的要点由此得到解答,GCC 得到了另一个提醒。谢谢大家。