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(もちろん、スペシャライゼーションを設定しません)、テンプレートを早期に拒否することはできなくなります。

executeエラーメッセージはResourceJob全体として特殊化する必要があることを示しているので、static_assertをに入れたかったのではないかと思います。したがって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

于 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 に答える