这个C ++模板代码是否有效? g ++编译它,但clang不会
我想用Fedora上的默认C ++标准库(4.6.2)编译一个小型的c ++程序。 铿锵本身编译好,只使用编译和运行良好的测试程序。
我的其他程序使用clang抱怨的绳索。
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/ropeimpl.h:433:2:error:use未声明的标识符'_Data_allocate'_Data_allocate(_S_rounded_up_size(__ old_len + __len));
针对此错误消息提交了针对叮当的错误,并且解析结果是正确的,库代码无效。
铿锵在这里是正确的。 在调用_Data_allocate时没有依赖于类型的参数,所以名称查找在模板定义时失败。
失败代码的上下文:
// Concatenate a C string onto a leaf rope by copying the rope data.
// Used for short ropes.
template <class _CharT, class _Alloc>
typename rope<_CharT, _Alloc>::_RopeLeaf*
rope<_CharT, _Alloc>::
_S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len)
{
size_t __old_len = __r->_M_size;
_CharT* __new_data = (_CharT*)
_Data_allocate(_S_rounded_up_size(__old_len + __len));
_RopeLeaf* __result;
uninitialized_copy_n(__r->_M_data, __old_len, __new_data);
uninitialized_copy_n(__iter, __len, __new_data + __old_len);
_S_cond_store_eos(__new_data[__old_len + __len]);
__try
{
__result = _S_new_RopeLeaf(__new_data, __old_len + __len,
__r->_M_get_allocator());
}
__catch(...)
{
_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len,
__r->_M_get_allocator());
__throw_exception_again;
}
return __result;
}
我的问题是,如果此代码无效,是否有一个简单的解决方法? g ++编译这个没关系。
挖掘libstdc ++源代码,看起来成员函数_Data_allocate
的定义是在模板_Rope_base
的定义中扩展__ROPE_DEFINE_ALLOCS
宏的_Rope_base
(注意模板实例化rope<_CharT, _Alloc>
公开扩展了_Rope_base<_CharT, _Alloc>
)。
您可以尝试进一步限定对_Data_allocate
的调用。 代替:
_Data_allocate(_S_rounded_up_size(__old_len + __len));
尝试:
_Rope_base<_CharT, _Alloc>::_Data_allocate(_S_rounded_up_size(__old_len + __len));
或者干脆:
_Base::_Data_allocate(_S_rounded_up_size(__old_len + __len));
由于受保护的typedef _Rope_base<_CharT, _Alloc> _Base;
在rope<_CharT, _Alloc>
的定义中。
编辑:我没有在本地安装Clang,但是我使用在线Clang 3.0编译器演示测试了这一点。
这个高度简化的版本无法使用Clang 3.0进行编译(错误:使用未声明的标识符'_Data_allocate'):
#include <cstddef>
#include <memory>
template <typename _CharT, class _Alloc>
class _Rope_base : public _Alloc
{
public:
typedef typename _Alloc::template rebind<_CharT>::other _DataAlloc;
static _CharT * _Data_allocate(std::size_t __n) {
return _DataAlloc().allocate(__n);
}
};
template <typename _CharT, class _Alloc = std::allocator<_CharT> >
class rope : public _Rope_base<_CharT, _Alloc>
{
protected:
typedef _Rope_base<_CharT, _Alloc> _Base;
public:
rope()
{
_Data_allocate(0);
}
};
int main()
{
rope<char> r;
}
通过以上面提到的方式限定对_Data_allocate
的调用,Clang 3.0成功编译它。
上一篇: Is this c++ template code valid? g++ compiles it but clang won't