Shaggi
Shaggi

Reputation: 1161

Specialization of single template argument

Consider the following code:

/* aclass.h */
class AClass
{
public:
    template<size_t N, class Vector>
        void aMethod(const Vector &);
};

/* aclass.inl */
// method for any N
template<size_t N, class Vector>
    void AClass::aMethod(const Vector &) { ... }

// method for N = 1
template<class Vector>
    void AClass::aMethod<1>(const Vector &) { ... }

/* main.cpp */
int main()
{
    AClass inst;
    std::vector<float> data;
    // calls method for any N
    inst.aMethod<20>(data);
    // calls method for N = 1
    inst.aMethod<1>(data);
}

I can't seem to find the correct syntax for specializing a single template argument of integer type - and not even sure if it is legal. I looked around a bit, but didn't find anyone with this problem...

These are the errors i get (from msvc):

error C2244 : 'AClass::aMethod' : unable to match function definition to an existing declaration
error C2768 : 'AClass::aMethod' : illegal use of explicit template arguments

How would i go on about solving this problem?

Upvotes: 0

Views: 62

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52471

There ain't no such thing as a partial specialization of a function template.

To achieve your goal, you could go through a helper class, which can be partially specialized:

class AClass;

template<size_t N, class Vector>
struct AMethodHelper {
  static void Do(AClass* pThis, const Vector&) {
    // General for N != 1
  }
};

template<class Vector>
struct AMethodHelper<1, Vector> {
  static void Do(AClass* pThis, const Vector&) {
    // Special for N == 1
  }
};

class AClass
{
public:
    template<size_t N, class Vector>
    void aMethod(const Vector & v) {
      AMethodHelper<N, Vector>::Do(this, v);
    }
};

Or, you could use two overloads selected with SFINAE:

class AClass
{
public:
    template<size_t N, class Vector>
    typename enable_if<N!=1>::type aMethod(const Vector &) {
          // General for N != 1
    }
    template<size_t N, class Vector>
    typename enable_if<N==1>::type aMethod(const Vector &) {
        // Special for N == 1
    }
};

Or, I suppose, you could just have one method with if (N == 1) inside. I suspect any decent compiler would be smart enough to eliminate dead code in any given instantiation.

Upvotes: 1

Related Questions