Reputation:
I've got two functions defined:
std::vector<ptr> find(const ptr&, const std::function<bool(const ptr&)>&, const std::function<bool(const ptr&)>&);
and
std::vector<ptr> find(const ptr&, const std::function<bool(const ptr&)>&, const std::function<bool(const std::vector<ptr>&)>&);
I'm trying to rewrite them as template function accepting template arguments for the functions, in order to avoid new/delete for the std::function and avoiding calling via a virtual function.
template<typename CHECK, typename DIVE>std::vector<ptr> find(const ptr&, const CHECK&, const DIVE&);
But the compiler gets confused as the template definition for both functions is identical. Is there some way to do this -- e.g. by using some static_assert that the argument must be convertable to a std::function with a certain argument set?
I'm bound to C++11...
Upvotes: 0
Views: 66
Reputation:
implementation for DIVE argument type vector
template<typename CHECK, typename DIVE>
std::vector<ptr> findImpl(
const ptr&pRoot,
const CHECK&rCheck,
const DIVE&rDive,
const std::integral_constant<bool, true>&);
implementation for DIVE argument type ptr
template<typename CHECK, typename DIVE>
std::vector<ptr> findImpl(
const ptr&pRoot,
const CHECK&rCheck,
const DIVE&rDive,
const std::integral_constant<bool, false>&);
forwarding to the implementation matching the argument type of DIVE
template<typename CHECK, typename DIVE>
std::vector<ptr> find(const ptr&pRoot, const CHECK&rCheck, const DIVE&rDive)
{ return findImpl(
pRoot,
rCheck,
rDive,
std::integral_constant<
bool,
std::is_convertible<
DIVE,
std::function<bool(const std::vector<ptr>&)>
>::value
>()
);
}
Upvotes: 0
Reputation:
Since both of your template arguments are predicates, you should use the std::predicate
concept:
template<std::predicate<const ptr&> CHECK, std::predicate<const ptr&> DIVE>
std::vector<ptr> find(const ptr&, const CHECK&, const DIVE&) {
// ...
}
Full example:
#include <concepts>
#include <vector>
struct ptr {};
template<std::predicate<const ptr&> CHECK, std::predicate<const ptr&> DIVE>
std::vector<ptr> find(const ptr&, const CHECK&, const DIVE&) {
return {};
}
bool foo(const ptr&);
bool bar(const ptr&);
int main() {
ptr p;
find(p, foo, bar);
find(p,
[](const ptr& p) { return true; },
[](const ptr& p) { return false; }
);
}
Upvotes: 2