Reputation: 179
Is there any way to pass std::max_element()
or std::min_element()
to template class method? For example:
#include <vector>
#include <algorithms>
template <typename T>
class A
{
public:
int fooMax()
{
return foo(std::max_element());
}
int fooMin()
{
return foo(std::min_element());
}
private:
std::vector<T> data_;
private:
int foo(??? func)
{
auto it = func(data_.begin(), data_.end());
int i = do_something();
return i;
}
};
I tried to use function pointers, but it did not compiled.
Upvotes: 0
Views: 561
Reputation: 118330
std::max_element
and std::min_element
are template functions, and you need to instantiate them:
template <typename T>
class A
{
public:
int fooMax()
{
return foo(&std::max_element<typename std::vector<T>::const_iterator>);
}
int fooMin()
{
return foo(&std::min_element<typename std::vector<T>::const_iterator>);
}
private:
std::vector<T> data_;
private:
template<typename func_type>
int foo(func_type func)
{
auto it=func(data_.begin(), data_.end());
return 0;
}
};
Tested with gcc 5.3.1 with -std=c++14
.
You may also choose to instantiate a std::vector<T>::iterator
instead, if you so choose.
Upvotes: 3
Reputation: 13988
You can use the lambda expressions for this:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
struct A {
vector<T> v;
A(vector<T> v): v(v) { }
template <class Lambda>
T element(Lambda &&lambda) {
return *lambda(v.begin(), v.end());
}
};
int main() {
vector<int> vi {1, 2, 3, 4, 5, 6};
A<int> a(vi);
cout << a.element([](typename vector<int>::iterator begin,
typename vector<int>::iterator end){
return max_element(begin, end);
}) << endl;
}
This way it should get inlined and thus efficient...
If you can use c++14 code would get even simpler:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
struct A {
vector<T> v;
A(vector<T> v): v(v) { }
T element(auto &&lambda) {
return *lambda(v.begin(), v.end());
}
};
int main() {
vector<int> vi {1, 2, 3, 4, 5, 6};
A<int> a(vi);
cout << a.element([](auto begin, auto end) {
return max_element(begin, end);
}) << endl;
}
Upvotes: 2
Reputation: 69874
not what you want to see, I know. But if you want to pass it as a function pointer...
#include <vector>
#include <algorithm>
int do_something();
template <typename T>
class A
{
public:
int fooMax()
{
return foo(std::max_element<const_iterator>);
}
int fooMin()
{
return foo(std::min_element<const_iterator>);
}
private:
std::vector<T> data_;
private:
using const_iterator = typename std::vector<T>::const_iterator;
using fp = const_iterator (*)(const_iterator, const_iterator);
int foo(fp func)
{
auto it = func(data_.begin(), data_.end());
int i = do_something();
return i;
}
};
Upvotes: 1