Apr 20, 2014 at 5:48pm UTC
I'm trying to generalize the following (working) code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#include <iostream>
#include <string>
#include <cmath>
int foo (int num) {return num;}
int foo (double num) {return std::round (num);}
int foo (std::string str) {return str.length();}
template <class T>
void predicate_and_action (const T& t) {
if (foo(t) == 5)
std::cout << "Hooray!" << std::endl;
}
template <class T>
void check (const T& t) {
predicate_and_action(t);
}
template <class FIRST, class ...REST>
void check (const FIRST& first, const REST&...rest) {
predicate_and_action (first);
check (rest...);
}
int main() {
check (5, 4.9, "smile" );
std::cin.get();
}
Output:
1 2 3
Hooray!
Hooray!
Hooray!
But the following attempt with PREDICATE_AND_ACTION template parameter fails to compile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#include <iostream>
#include <string>
#include <cmath>
int foo (int num) {return num;}
int foo (double num) {return std::round (num);}
int foo (std::string str) {return str.length();}
template <class T>
void predicate_and_action (const T& t) {
if (foo(t) == 5)
std::cout << "Hooray!" << std::endl;
}
template <class PREDICATE_AND_ACTION, class T>
void check (PREDICATE_AND_ACTION pred_action, const T& t) {
pred_action(t);
}
template <class PREDICATE_AND_ACTION, class FIRST, class ...REST>
void check (PREDICATE_AND_ACTION pred_action, const FIRST& first, const REST&...rest) {
pred_action(first);
check (pred_action, rest...);
}
int main() {
check (predicate_and_action, 5, 4.9, "smile" );
std::cin.get();
}
Template argument deduction failed, it says. And using pred_action<T> and pred_action<FIRST> only makes it worse. How to fix this? Do we need to use a visitor pattern or something like that?
Last edited on Apr 20, 2014 at 9:34pm UTC
Apr 21, 2014 at 12:34am UTC
Is what I'm trying to achieve impossible because predicate_and_action<T> needs to be known at compile time? I'm sure there is a workaround of some sort.