此 C++ 模板代码有效吗?G++编译它,但Clang不会
Is this c++ template code valid? g++ compiles it but clang won't
我正在尝试用Fedora上的默认c++标准库(4.6.2)使用clang编译一个小的c++程序。Clang本身可以很好地编译,测试程序也可以很好地编译和运行。
我的另一个程序使用了clang抱怨的rope。
/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是正确的,库代码是无效的。
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;
}
我的问题是,如果这个代码是无效的,是否有一个简单的解决方案?c++可以编译这个。
从libstdc++源代码中可以看出,成员函数_Data_allocate
的定义是在模板_Rope_base
的定义中扩展了__ROPE_DEFINE_ALLOCS
宏(注意,模板实例化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));
因为rope<_CharT, _Alloc>
的定义中保护了typedef _Rope_base<_CharT, _Alloc> _Base;
。
EDIT:我没有在本地安装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成功地编译了它。
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 没有 srcs 的 Bazel cc_library 不会自行编译
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- Mingw-64 在构建和安装后不会编译 openCV 代码
- 编译器不会使用 -std=c++11 编译智能指针
- 如何让谷歌测试正常运行。测试总是失败。(它不会编译)
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 如何使用我构建的库,而不会从源代码出错,但不为我自己的项目编译?
- 从DLL导出函数,LoadLibrary()需要用TEXT转换的字符串才能编译而不会出错
- 将函数类型作为模板参数传递不会编译
- Clang不会编译GCC会编译的模板专业化
- 使用成员函数创建std::函数不会编译
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- CodeLite 不会检测(安装)MinGW - 即使使用手动配置也不会编译
- 如果条件取决于模板类型并且在编译时已知,是否可以保证C++编译器不会生成分支?
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- make_unique 不会为创建单一实例进行编译
- 为什么 boost 文件系统和 libpq-fe 标头不会在同一个文件中编译
- GCC 中使用 -O3 的共享库编译不会导出与 -O0 中那样多的符号