Hemant Bhargava
Hemant Bhargava

Reputation: 3585

using template arguments to specify policy

I got to know that we can also pass template arguments to choose which function should execute. I found them good alternative to function pointers since function pointers has run time cost but template parameters does not. Also, template parameters can be made inline whereas function pointers are not.

Alright then, this is what I wrote to depict my understanding on it. I came close but missing some minor detail somewhere.

template<class T>
class String {
  public:
    T str;
    String() { std::cout << "Ctor called" << std::endl; }
};  

template<class T, class C>
int compare(const String<T> &str1,
            const String<T> &str2) {
  for (int i = 0; (i < str1.length()) && (i < str2.length()); ++i) {
    if (C::eq(str1[i], str2[i])) {
      return false;
    }   
  }   
  return true;
}   

template<class T>
class Cmp1 {
  static int eq(T a, T b) { std::cout << "Cmp1 called" << std::endl; return a==b; }
};  

template<class T>
class Cmp2 {
  static int eq(T a, T b) { std::cout << "Cmp2 called" << std::endl; return a!=b; }
};  

int main() {
  String<std::string> s;
  s.str = "Foo";
  String<std::string> t;
  t.str = "Foo";
  compare<String<std::string>, Cmp1<std::string> >(s, t);
  // compare(s, t);
}

Details of the code:

I have an class String, which take an parameter and create member function of that type. I have an compare function, which takes two String& arguments. Comparison function is passed to it. Cmp1 and Cmp2 are two compare functions.

compare<String<std::string>, Cmp1<std::string> >(s, t);

does not get compile here. I tried some other ways to call but in vain.

Upvotes: 1

Views: 89

Answers (1)

ForEveR
ForEveR

Reputation: 55897

Looks like you want something like that:

#include <iostream>
#include <string>

template<class T>
class String {
  public:
    T str;
    String() { std::cout << "Ctor called" << std::endl; }
};  

template<class T, class C>
int compare(const String<T> &str1,
            const String<T> &str2) {
  for (int i = 0; (i < str1.str.length()) && (i < str2.str.length()); ++i) {
    if (C::eq(str1.str[i], str2.str[i])) {
      return false;
    }   
  }   
  return true;
}   

template<class T>
class Cmp1 {
public:
  static int eq(T a, T b) { std::cout << "Cmp1 called" << std::endl; return a==b; }
};  

template<class T>
class Cmp2 {
public:
  static int eq(T a, T b) { std::cout << "Cmp2 called" << std::endl; return a!=b; }
};  

int main() {
  String<std::string> s;
  s.str = "Foo";
  String<std::string> t;
  t.str = "Foo";
  compare<std::string, Cmp1<char> >(s, t);
  // compare(s, t);
}

code

Explanations: You already have String in definition of compare, you need to just send T which is std::string in your case.

You are trying to go through entire std::string, in compare, so, now your code compiles.

You calling cmp on str[index], that is actually char, so you need to call cmp with char template argument.

Upvotes: 1

Related Questions