1

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

任何人都可以看到问题吗?

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>;

谢谢!

4

3 回答 3

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这将提供模板将使用的替代定义if Tis int

于 2012-08-14T21:19:42.833 回答
1
IResourceJob* job = new ResourceJob<int>;

失败,因为该类ResourceJob<int>不是从 派生的IResourceJob

代码应该是

template<>
class ResourceJob<int> : public IResourceJob
{
     public:
     void execute()
     {
         // test.
     }
 };
于 2012-08-14T21:20:12.987 回答
1

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

template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };
于 2012-08-14T21:20:41.880 回答