2

I have a template method inside a template class.
I read that a method can not be specialized without specialize the class before.
But I want to factorize some of theses methods, is it possible ?

Example :

class One {
public:
  static const int number = 1;
};

class Two {
public:
  static const int number = 2;
};    

template<typename num> class A  {
private:
  num n;

public:
  template<typename type>
  void multiplyBy(); // by 1 if <int> or 1,5 if <float>
}; // A

template<> template<> void A<One>::multiplyBy<int>() {
  std::cout << 1.0*n.number << std::endl;
}

template<> template<> void A<One>::multiplyBy<float>() {
  std::cout << 1.5*n.number << std::endl;
}

template<> template<> void A<Two>::multiplyBy<int>() {
  std::cout << 1.0*n.number << std::endl;
}

template<> template<> void A<Two>::multiplyBy<float>() {
  std::cout << 1.5*n.number << std::endl;
}

int main() {
  A<One> aOne;
  A<Two> aTwo;
  aOne.multiplyBy<int>();   // 1
  aOne.multiplyBy<float>(); // 1.5
  aTwo.multiplyBy<int>();   // 2
  aTwo.multiplyBy<float>(); // 3

  return 0;
}

A stackoverflow related question : C++ specialization of template function inside template class
In particular this comment : C++ specialization of template function inside template class

Have I to deduct than there is no way to factorize multiplyBy(), for one for int and an other for float ?
As english is not my natural language maybe I miss something simple, maybe a workaround with partial-specialization.

Edit : put A::n in private to match even better my problem.

Community
  • 1
  • 1
Benjamin
  • 490
  • 1
  • 5
  • 19

2 Answers2

2

You might use tag dispatching:

#include <iostream>

class One {
public:
  static const int number = 1;
};

class Two {
public:
  static const int number = 2;
};

template<typename num>
class A  {
    public:
    num n;

    private:
    template<typename> struct Tag {};

    void multiplyBy(Tag<int>) {
        std::cout << 1.0*n.number << std::endl;
    }

    void multiplyBy(Tag<float>) {
        std::cout << 1.5*n.number << std::endl;
    }

    public:
    template<typename type>
    void multiplyBy() {
        multiplyBy(Tag<type>());
    }
};


int main() {
  A<One> aOne;
  A<Two> aTwo;
  aOne.multiplyBy<int>();   // 1
  aOne.multiplyBy<float>(); // 1.5
  aTwo.multiplyBy<int>();   // 2
  aTwo.multiplyBy<float>(); // 3

  return 0;
}
1

But I want to factorize some of theses methods, is it possible ?

You probably know that you cannot use:

template<> template<> void A<One>::multiplyBy<int>() {
  std::cout << 1.0*n.number << std::endl;
}

without specializing A<One>.

You can do something along the lines of:

#include <iostream>

class One {
public:
  static const int number = 1;
};

class Two {
public:
  static const int number = 2;
};    

template<typename num, typename type = int> struct MultiplyBy {
   static void doit(num n)
   {
      std::cout << 1.0*n.number << std::endl;
   }
};

template<typename num> struct MultiplyBy<num, float> {
   static void doit(num n)
   {
      std::cout << 1.5*n.number << std::endl;
   }
};

template<typename num> class A  {
public:
  num n;

  template<typename type>
  void multiplyBy()
  {
     MultiplyBy<num, type>::doit(n);
  }
};


int main() {
  A<One> aOne;
  A<Two> aTwo;
  aOne.multiplyBy<int>();   // 1
  aOne.multiplyBy<float>(); // 1.5
  aTwo.multiplyBy<int>();   // 2
  aTwo.multiplyBy<float>(); // 3

  return 0;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • This answer do not work in my particulary case. MultiplyBy() have to acces privates members of class A. I was not enough acccurate in my question. – Benjamin Feb 10 '15 at 08:25
  • `MultiplyBy` doesn't need access to private members of `A`. When `A::multiplyBy()` calls `MultiplyBy::doit()`, it passes its private member data by value. – R Sahu Feb 10 '15 at 14:51