来自模板类?

时间:2012-08-14 21:16:58

标签: c++ templates

我正在尝试使用以下代码,但无法完成它。

有人能看到问题吗?

class IResourceJob
{
public:
   virtual ~IResourceJob() {}

   virtual void execute() = 0;
};

template<typename T>
class ResourceJob : public IResourceJob
{
public:
   void execute()
   {
      static_assert(false, "Specialised ResourceJob<T> not defined!");
   }
};

template<>
class ResourceJob<int>
{
public:
   void execute()
   {
       // test.
   }
};

以下用法给出了编译错误:

IResourceJob* job = new ResourceJob<int>;

谢谢!

3 个答案:

答案 0 :(得分:2)

编译器为任何永远无法实例化的模板提供错误。对于类模板的成员函数(假设您的意思是static_assert),这是正确的,因此编译器可以为您提供诊断。

您希望条件取决于T并巧妙地使其在实例化时始终评估为false 。例如

template<typename T>
struct always_false : std::false_type {};

template<typename T>
class ResourceJob : public IResourceJob
{
public:
   void execute()
   {
      static_assert(always_false<T>::value, 
        "Specialised ResourceJob<T> not defined!");
   }
};

由于编译器无法知道用户是否会对always_false进行专门化(当然,您不会这样做),因此无法再提前拒绝该模板。

我还怀疑您是否想将static_assert放入execute,因为您的错误消息表明ResourceJob整体需要专门化。因此,将static_assert放在成员函数之外的类体中。如果您希望用户专门化整个模板,而只需要成员函数,则用户需要说

// either "inline" and in the header, or not "inline" and in the .cpp file, but then 
// put this into the header: template<> void ResourceJob<int>::execute();
template<> inline void ResourceJob<int>::execute() {

}

这将提供execute的替代定义,如果Tint,模板将使用该定义。

答案 1 :(得分:1)

IResourceJob* job = new ResourceJob<int>;

失败,因为类ResourceJob<int>不是来自IResourceJob

代码应为

template<>
class ResourceJob<int> : public IResourceJob
{
     public:
     void execute()
     {
         // test.
     }
 };

答案 2 :(得分:1)

您还需要派生模板专业化,如:

template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };