2011-12-28 3 views
2

Я пытаюсь скомпилировать небольшую программу C++, используя clang со стандартной стандартной библиотекой C++ (4.6.2) в Fedora. Сам Clang компилирует все в порядке, а тестовая программа использует только компиляции и работает нормально.Действительно ли этот код шаблона C++? g ++ компилирует его, но clang не будет

В моей другой программе используются веревки, которые жалуются.

/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/ropeimpl.h:433:2: error: use of undeclared identifier '_Data_allocate' _Data_allocate(_S_rounded_up_size(__old_len + __len));

bug был подан против лязга за это сообщение об ошибке, и разрешение было лязг правильно, библиотечный код неверен.

Clang is correct here. There are no type-dependent arguments in the call to _Data_allocate, so name lookup fails at template definition time.

Контекст неисправного кода:

// 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 ++ компилирует это нормально.

+0

Считаете ли вы, что хотите сделать отчет об ошибке на странице http://gcc.gnu.org/bugzilla/? –

ответ

4

Digging через источник libstdC++, представляется, что определение функции члена _Data_allocate результатов из расширению __ROPE_DEFINE_ALLOCS макрокоманды в определении шаблона _Rope_base (обратите внимание, что шаблон экземпляр rope<_CharT, _Alloc> публично расширяет _Rope_base<_CharT, _Alloc>).

Вы можете попробовать отправив вызов на номер _Data_allocate. Вместо того, чтобы:

_Data_allocate(_S_rounded_up_size(__old_len + __len)); 

Try:

_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>.

EDIT: У меня нет Clang, установленного локально, но я проверил это с помощью online Clang 3.0 compiler demo.

Это очень урезанный вариант не может скомпилировать с 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 успешно в его компиляции.

+3

+1 Кроме того, если вы хотите исправить библиотеку, вы также можете квалифицировать вызов с помощью 'this':' this -> _ Data_allocate' становится зависимым именем, а это означает, что разрешение откладывается до замены параметров и правильного члена функция в базовом шаблоне будет найдена. Другим решением было бы добавить 'using _Base :: _ Data_allocate;' к шаблону класса 'rope', который приведет базовую функцию в область видимости. –

+1

Я попробовал this-> но clang пожаловался на "error: недопустимое использование 'this' вне нестатической функции-члена. –

+1

@ Daniel: добавление 'using _Base :: _ Data_allocate;' отлично работало для меня (как должно быть) на демо-странице Clang. –