2012-05-06 8 views
0

Я портирую http://www.drdobbs.com/embedded-systems/225700666 на Keil MDK на ARM микропроцессоры. Структура компилирует и отлично работает с использованием gcc на моем рабочем столе, но используя Keil компилятор дает мне ошибку:Ошибка: «неполный тип недопустим» при портировании проекта

logging/singleton.h(65): error: #70: incomplete type is not allowed

После кода показывает реализацию singleton где я получаю эту ошибку. Откуда возникает эта ошибка?

namespace logging { 

    namespace detail { 

     template <typename T> 
     class singleton 
     { 
     private: 
      struct obj 
      { 
      obj() { singleton<T>::instance(); } 
      inline void empty() const { } 
      }; 
      static obj __obj; 

      singleton(); 

     public: 
      typedef T obj_type; 

      static obj_type & instance() 
      { 
      static obj_type obj; // <-- Here I get this error 

      __obj.empty(); 

      return obj; 
      } 
     }; 
     template <typename T> 
     typename singleton<T>::obj 
     singleton<T>::__obj; 

    } /* detail */ 
} /* logging */ 

Edit: singleton получает экземпляр здесь

template <typename log_t, typename T> 
struct Obj { 
    static return_type& obj() { 
     typedef singleton<return_type> log_output; 
     return log_output::instance(); 
    } 
}; 

где return_type является ЬурейеЕ:

typedef R return_type; 

и это параметр родительского шаблона:

template<typename Level = ::logging::Void, typename R = loggingReturnType> 
    class Logger { 
     ... 
    }; 

loggingReturnType поступательно declarated выше определение класса:

struct loggingReturnType; 

Edit 2: Это loggingReturnType получает генерируется через следующие Makro.

#define LOGGING_DEFINE_OUTPUT(BASE)           \ 
namespace logging {               \ 
    struct loggingReturnType : public BASE {         \ 
      /*! \brief The provided typedef is used for compile time   \ 
      *   selection of different implementation of the   \ 
      *   %logging framework. Thus, it is necessary    \ 
      *   that any output type supports this type    \ 
      *   definition, why it is defined here.     \ 
      */                \ 
      typedef BASE output_base_type;         \ 
     };                 \ 
} 

Этот makro вызывается в заголовке конфигурации.

Редактировать 3: Ее ссылка на выход препроцессора: http://www.pasteall.org/31617/cpp. Этот файл компилируется с использованием g++. Определение loggingReturnType является последним до main - поэтому синглтон не является точным типом, но тем не менее он работает. Я также посмотрел вывод препроцессора компилятора Keil, и это почти то же самое.

А как же здесь не так?

+0

Какой тип вы переходите в шаблон singleton? Похоже, что тип T является неполным (абстрактным). –

+1

Тип _incomplete_ не совпадает с типом _abstract_. –

+0

Я добавил экземпляр этого синглтона. – Razer

ответ

2

Согласно информации, помещенной здесь, сообщение об ошибке имеет смысл. Код пытается создать экземпляр объекта в стеке. Тип этого объекта объявляется только вперед, но в то время компилятор не может определить определение.

Вам необходимо сделать определение этого типа доступным для компилятора до того, как оно создаст экземпляр этого типа.

+0

Я добавил код для определения этого типа. Может быть, проблема в порядке компиляции? – Razer

+0

@Razer Это заголовок конфигурации, который вызывает макрос, включенный в блок трансляции (прямо или косвенно) до того, как этот тип используется? – selalerer

+0

Файл 'Logger.h' содержит экземпляр singleton и определение makro. Макро получает вызов в 'logging.h' - но это делается после включения' Logger.h'. Теперь я запутался - как можно «Logger.h» привести такой синглтон? @selalerer Да, это - если я создаю ошибку в этом файле, компилятор кричит.К сожалению, я не знаю, как вывести блок перевода с помощью компилятора Keil. – Razer