错误:移植项目时“不允许不完整类型”

时间:2012-05-06 10:39:45

标签: c++ templates singleton incomplete-type

我正在为Keil MDK个微处理器移植http://www.drdobbs.com/embedded-systems/225700666ARM。框架在我的桌面上使用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 */

编辑: 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:

typedef R return_type;

这是父模板的参数:

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

loggingReturnType在类定义上方正向声明:

struct loggingReturnType;

编辑2: 通过以下makro生成此loggingReturnType

#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编译器的预处理器输出,它几乎相同。

那么这里出了什么问题?

1 个答案:

答案 0 :(得分:3)

根据您在此处提供的信息,错误消息非常有意义。代码试图在堆栈上创建对象的实例。此对象的类型仅向前声明,但当时编译器没有可用的定义。

在创建此类型的实例之前,您需要使编译器可以使用此类型的定义。