У меня та же функция с той лишь разницей, что она будет либо увеличиваться, либо уменьшаться. Я хотел бы обобщить это.
template<typename O>
void f(int& i, O op){
op(i);
}
int main() {
int i;
f(i,operator++);
f(i,operator--);
return 0;
}
Как я могу сделать эту работу?
Другой вариант — использовать функционал std :: plus или иметь две функции, но я бы предпочел это решение, если это возможно. Спасибо.
Просто используйте лямбду:
template<typename O>
void f(int& i, O op){
op(i);
}
int main() {
int i;
f(i,[] (int& x) { ++x; });
f(i,[] (int& x) { --x; });
return 0;
}
Также не ясно, хотите ли вы пост- или прекремент.
Как отмечает @ T.C. если вы хотите сохранить семантику обычного оператора, вы можете добавить оператор return.
Вот один вариант (есть много возможных решений), который также работает до C ++ 11:
enum OpType { increment, decrement };
template <OpType op> void f(int &i);
template<> void f<increment>(int &i) { ++i; }
template<> void f<decrement>(int &i) { --i; }
Использование:
f<increment>(i);
Чтобы сохранить вашу кодовую базу аккуратной, вы, вероятно, захотите использовать некоторую область видимости, поэтому либо используйте перечисление scoped в C ++ 11, либо пространство имен.
в указанном вами случае использования typename O является унарной функцией без состояния, которую можно смоделировать с помощью простого указателя на функцию:
#include <iostream>
int& increment(int& i) {
++i;
return i;
}
int& decrement(int& i) {
--i;
return i;
}
template<typename O>
void f(int& i, O op){
op(i);
}
using namespace std;
int main()
{
int i = 0;
f(i, increment);
cout << i << endl;
f(i, decrement);
cout << i << endl;
return 0;
}
выход:
1
0