我正在查看一些大量使用模板的代码。它在 GCC 上编译得很好,但在 VS(在 2003 - 2010 beta 1 上测试)上编译得很好,在语法分析期间它失败了。不幸的是,我对代码结构的了解还不够,无法减少问题并仅在几行内重现问题,所以我只能猜测原因。我希望这里有人能指出我正确的方向。
我们有
template< class UInt, typename IntT,
bool is_signed = std::numeric_limits<IntT>::is_signed >
struct uii_ops_impl;
// ....
template<class UInt>
struct uii_ops_impl< UInt,
typename make_signed<typename UInt::digit_type>::type, true >
{
typedef UInt unbounded_int_type;
typedef typename make_signed< typename unbounded_int_type::digit_type >::type
integral_type;
// ...
static void add(unbounded_int_type& lhs, integral_type rhs);
// ...
};
template<class UInt>
void uii_ops_impl<
UInt, typename make_signed<typename UInt::digit_type>::type,
true >::add(unbounded_int_type& lhs, integral_type rhs)
{
// ....
}
在 VS 上编译时,它返回的第一条错误消息(在许多错误消息中)是
: 错误 C2065: '
unbounded_int_type
' : 未声明的标识符
我的意思是,指向typedef吧?:-S
编辑:
好像有什么关系
typename make_signed<typename UInt::digit_type>::type
用作模板参数。在其余的代码中,成员函数参数中使用的类似 typedef 编译得很好。到目前为止,我能看到的唯一区别是其他情况都没有将上述行作为模板参数。make_signed
来自 Boost.TypeTraits。
编辑:
好吧,也许不是这样,因为完全相同的事情是在另一个编译好的文件中完成的。唔...
赏金编辑:
好的,我认为在这一点上很明显,问题实际上并不在于编译器抱怨的地方。只有在该特定点的两个成员函数定义失败。事实证明,显式限定参数仍然无法编译。唯一直接的解决方案是定义内联函数。这通过了语法分析。但是,当尝试安装模板时,VS 现在失败了,因为std::allocator<void>
没有size_type
成员。原来 VS 有一个std::allocator<T>
for T=void 的专业化,它没有声明 a size_type
。我认为size_type
是所有分配器的必需成员?
所以现在的问题是,在语法分析过程中,什么可能会严重破坏 VS,以至于它抱怨完全不相关的非问题是错误,你如何调试这样的代码?
ps 对于那些有太多空闲时间的人,我试图在 VS 中编写的代码是 Kevin Sopp在Boost 沙箱中的 mp_math,它基于libtommath。