错误:无效使用不完整类型(可能是定义问题)

时间:2015-09-08 11:40:14

标签: c++ templates template-specialization partial-specialization

我已经在这个问题上苦苦挣扎了一段时间,似乎无法通过所有模板和专业化来解决问题。我想我错过了静态函数internal_set_BC的定义,但我不确定。当我编译下面的代码时,我收到以下错误:

test.cc:37:49: error: invalid use of incomplete type ‘class RT<2, D>’
 static void RT<2, D>::internal_set_BC(D& d, T& t)
                                                 ^
test.cc:19:7: error: declaration of ‘class RT<2, D>’
 class RT: public BC<n, D>
       ^
test.cc:41:49: error: invalid use of incomplete type ‘class RT<3, D>’
 static void RT<3, D>::internal_set_BC(D& d, T& t)
                                                 ^
test.cc:19:7: error: declaration of ‘class RT<3, D>’
 class RT: public BC<n, D>

简化代码如下:

class A {};
class B {};
class C {};
class E {};

template <int n>
class Base
{};

template <int n, typename D>
class BC: public Base<n>
{
public:
  virtual void set_BC(D& d, A& a) =0;
  virtual void set_BC(D& d, B& b) =0;
};

template <int n, typename D> 
class RT: public BC<n, D>   
{ 
public: 
  void set_BC(D& d, A& a)
  {internal_set_BC(d, a);}
  void set_BC(D& d, B& b)
  {internal_set_BC(d, b);}
private:
  template <typename T> 
  static void internal_set_BC(D& d, T& t);   
};

template <typename D, typename T>
static void RT<2, D>::internal_set_BC(D& d, T& t)
{//code
}
template <typename D, typename T>
static void RT<3, D>::internal_set_BC(D& d, T& t)
{//code
}

此外,当我尝试使用此代码实例化internal_set_BC时:

template void RT<2, C>::internal_set_BC(C& d, A& t);

我收到此错误:

test.cc:45:51: error: explicit instantiation of ‘static void RT<n, D>::internal_set_BC(D&, T&) [with T = A; int n = 2; D = C]’ but no definition available [-fpermissive]
 template void RT<2, C>::internal_set_BC(C& d, A& t);

这支持了我对上述代码中缺少定义的怀疑。

你的帮助很高。

2 个答案:

答案 0 :(得分:2)

你做不到。你只能为完全专业化做这件事:

template <>
template <typename T>
static void RT<2, int>::internal_set_BC(int& d, T& t)
{//code
}

int就是一个例子。你应该编写部分类专门化。

template<typename D>
class RT<2, D> : public BC<2, D>
{
// public functions set_BC.
private:
   template <typename T>
   static void internal_set_BC(D& d, T& t);
};

template <typename D>
template <typename T>
void RT<2, D>::internal_set_BC(D& d, T& t)
{//code
}

你也可以写这样的东西,仅专攻internal_set_BC

template<int n, typename D, typename Impl>
class RT_base : public BC<n, D>
{
public:
  void set_BC(D& d, A& a)
  {
     Impl::internal_set_BC(d, a);
  }
  void set_BC(D& d, B& b)
  {
     Impl::internal_set_BC(d, b);
  }
};

template <int n, typename D>
class RT: public RT_base<n, D, RT<n, D> >
{
   friend class RT_base<n, D, RT<n, D> >;
   template <typename T> 
   static void internal_set_BC(D& d, T& t);   
};

template<typename D>
class RT<2, D> : public RT_base<2, D, RT<2, D> >
{
   friend class RT_base<2, D, RT<2, D> >;
   template <typename T>
   static void internal_set_BC(D& d, T& t);
};

template <typename D>
template <typename T>
void RT<2, D>::internal_set_BC(D& d, T& t)
{//code
}

或更简单,没有CRTP

template<int n, typename D>
class RT_Base : public BC<n, D>
{
protected:
   template<typename T>
   static void internal_set_BC(D& d, T& t);
};

template<typename D>
class RT_Base<2, D> : public BC<2, D>
{
protected:
   template <typename T>
   static void internal_set_BC(D& d, T& t);
};

template <typename D>
template <typename T>
void RT_Base<2, D>::internal_set_BC(D& d, T& t)
{//code
}

template<int n, typename D>
class RT : public RT_Base<n, D>
{
public:
  void set_BC(D& d, A& a)
  {
     this->internal_set_BC(d, a);
  }
  void set_BC(D& d, B& b)
  {
     this->internal_set_BC(d, b);
  }
};

答案 1 :(得分:1)

您的代码中还有另一个问题。 你已经定义了

virtual void set_BC(D& d, A& a) =0;

class BC中,但您已实施(在class RT

void set_BC(const D& d, A& a)

额外const使第二个函数不是覆盖,因此RT仍然是抽象的。