这个c ++模板代码有效吗? g ++编译它但clang不会

时间:2011-12-28 22:38:25

标签: c++ templates clang libstdc++

我试图在Fedora上使用clang和默认的C ++标准库(4.6.2)编译一个小的c ++程序。 Clang本身编译好,测试程序只使用编译并运行良好。

我的其他程序使用绳索抱怨抱怨。

  

/usr/lib/gcc/x86_64-redhat-linux/4.6.2 /../../../../包括/ C ++ / 4.6.2 / EXT / ropeimpl.h:433:2:   错误:使用         未声明的标识符'_Data_allocate'           _Data_allocate(_S_rounded_up_size(__ old_len + __len));

针对此错误消息向clang提交了bug,并且解决方法是正确的,库代码无效。

  

Clang在这里是正确的。在。中没有类型相关的参数   拨电至   _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 ++编译好了。

1 个答案:

答案 0 :(得分:4)

通过libstdc ++源代码,似乎成员函数_Data_allocate的定义来自模板__ROPE_DEFINE_ALLOCS定义中_Rope_base宏的扩展(请注意模板实例化{ {1}}公开扩展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;

编辑:我没有在本地安装Clang,但我使用online Clang 3.0 compiler demo对其进行了测试。

这个高度精简的版本无法使用Clang 3.0进行编译(错误:使用未声明的标识符'_Data_allocate'):

rope<_CharT, _Alloc>

通过以上述建议的方式对#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; } 的调用进行限定,Clang 3.0成功编译了它。