I'm trying to create a concept that can be used to safe check that a functor has a certain criteria.
This is my code right now:
template<typename T>
void fetch(T&& f)
{
fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());
}
template<typename T, typename... Args>
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
I use fetch to take a functor object and then use fetch_helper to operate on it. However I want to implement pref. a concept or type trait that would check that the arguments types are unique (which I already have an implemented concept for IsUnique<T...>). So that the program doesnt compile if the functor doesnt follow the criteria.
// compiles
fetch([](int h){
});
// doesnt compile
fetch([](int h, int j){
});
How can I apply my constrait IsUnique to the args of the functor object in fetch? I tried adding the requires concept to my helper function but that still allows fetch to be called with bad arguments. I somehow has to apply the constraint of the arguments in fetch.
Like this?
template<typename T, typename... Args>
requires IsUnique<Args...>
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
template<typename T>
requires requires (T&& f) {fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());}
void fetch(T&& f)
{
fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());
}
If I understand you right, you want something like this:
// TypeTraits if IsUnique is a typical trait inheriting from std::true_type or std::false_type
template<typename T, typename... Args>
std::enable_if_t<IsUnique<Args...>::value> fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
// Concept
template<typename T, typename... Args> requires (IsUnique<Args...>)
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
If you want to check already in fetch you can add a constraint whether fetch_helper is callable with the appropriate arguments (basically repeating the code inside).
Related
I'd like to create a wrapper for std::unique_ptr<T> and std::make_unique<T> because I think they look ugly and take too long to type. (Yes, I'm that kind of person).
I have completed my UniquePtr type alias with no problem but cannot get my MakeUnique to work. It seems to be a bit of a rabbit hole, and was wondering if anyone here might be able to give me a hand with this?
What I have so far:
template <class T>
using UniquePtr = std::unique_ptr<T>;
template<typename T, typename... Args>
UniquePtr<T> MakeUnique<T>(Args... args) // recursive variadic function
{
return std::make_unique<T>(args);
}
Many thanks in advance!
You need to forward properly the values, and you need to expand the pack.
First, make it compile:
template<typename T, typename... Args>
UniquePtr<T> MakeUnique(Args... args) // not recursive
{ // ^---- no need for <T> when defining function template
return std::make_unique<T>(args...); // the ... expands the pack
}
Then, you need to forward, because args... will copy everything. You want to move rvalues, and copy lvalues:
template<typename T, typename... Args>
UniquePtr<T> MakeUnique(Args&&... args)
{
return std::make_unique<T>(std::forward<Args>(args)...);
}
I have problem similar to Passing different lambdas to function template in c++ but now with wrappers created by std::bind instead of lambdas.
I have two overloads of method Add that take different forms of std::function:
template<typename T>
struct Value
{
T value;
};
template <typename T>
void Add(Value<T> &value, function<bool()> predicate)
{
}
template <typename T>
void Add(Value<T> &value, block_deduction<function<bool(const Value<T> &)>> predicate)
{
}
This now works fine with lambdas but fails with functors bound with std::bind:
struct Predicates
{
bool Predicate0() { return true; }
bool Predicate1(const Value<int> &) { return true; }
};
Predicates p;
Add(i, std::bind(&Predicates::Predicate0, &p));
fails with
error C2668: 'Add': ambiguous call to overloaded function
and
Add(i, std::bind(&Predicates::Predicate1, &p, _1));
fails with static assert (Visual C++ 2015, Update 3):
tuple index out of bounds
Is there a way to make it work both with lambdas and bound functors? I would think of using SFINAE to enable the individual overload based on is_bindable_expression and checking the argument type but I'm failing to put it together.
Stop using std::bind. It is a mess of random features and quirks.
Todays quirk is that std::bind will accept an unlimited number of arguments and discard any extra ones. Tomorrow you might run into the fact that passing std::bind result to std::bind does strange magic.
std::bind was ported over to boost at the same time lambdas where added to the language. Lambdas solve almost every problem bind does in just as clear syntax and fails to have the myraid of quirks bind does, especially post C++14 when auto lambdas are available. (Most C++11 compilers also supported auto lambda).
You can write functions so that one or the other is the preferred overload when they both apply. But doing so adds a pile of noise to your interface, and in this case about the only reason why you'd want that preference is because std::bind is doing something stupid.
Engineering around a poorly designed bit of std library is not worth it. Simply stop using that poorly designed bit of std library, or at point of use cast explicitly.
Failing that, do this:
template <class T, class F,
std::enable_if_t<
std::is_convertible<
std::result_of_t<std::decay_t<F> const&(Value<T> const&)>,
bool
>{}, int
> = 0
>
void Add(Value<T> &value, F&& f)
{
// do pass f Value<T>
}
template <class T, class F,
std::enable_if_t<
!std::is_convertible<
std::result_of_t<std::decay_t<F> const&(Value<T> const&)>,
bool
>{}
&& std::is_convertible<
std::result_of_t<std::decay_t<F> const&()>,
bool
>{}, int
> = 0
>
void Add(Value<T> &value, F&& f)
{
// do not pass f Value<T>
}
where we throw some nasty SFINAE detection on which of the two overloads you want to use, and explicitly prefer one.
This is not worth it.
I don't think you can do what you want.
You can use is_bind_expression to check if your argument is a type produced by a call to std::bind, but there is no way to tell how many arguments the callable expects. As cpplearned mentioned in the comments, this is a feature of std::bind:
If some of the arguments that are supplied in the call to g() are not
matched by any placeholders stored in g, the unused arguments are
evaluated and discarded.
That means that both overloads are equally valid.
If you don't mind sharing the same overload for all bind results, you can pass all the parameters and let them be discarded at will:
template <typename T>
void AddImpl(Value<T> &value, function<bool()> predicate, std::false_type)
{
predicate();
}
template <typename T>
void AddImpl(Value<T> &value, block_deduction<function<bool(const Value<T> &)>> predicate, std::false_type)
{
predicate(value);
}
template <typename T, typename U>
void AddImpl(Value<T>& value, U&& bind_expression, std::true_type)
{
bind_expression(value);
}
template<typename T, typename U>
void Add(T&& t, U&& u)
{
AddImpl(std::forward<T>(t), std::forward<U>(u), std::is_bind_expression<std::decay_t<U>>{});
}
demo
But this is similar to using boolean parameters. In my opinion it'd be better for readability to dispatch on properly named tags:
template <typename T>
void AddImpl(Value<T> &value, function<bool()> predicate, tag::default_)
{
predicate();
}
template <typename T>
void AddImpl(Value<T> &value, block_deduction<function<bool(const Value<T> &)>> predicate, tag::default_)
{
predicate(value);
}
template <typename T, typename U>
void AddImpl(Value<T>& value, U&& bind_expression, tag::bind)
{
bind_expression(value);
}
template<typename T, typename U>
void Add(T&& t, U&& u)
{
AddImpl(std::forward<T>(t), std::forward<U>(u), tag::get_tag<std::decay_t<U>>{});
}
with tags defined as
namespace tag
{
struct default_{};
struct bind{};
template<typename T, typename = void>
struct get_tag : default_ {};
template<typename T>
struct get_tag<T, std::enable_if_t<std::is_bind_expression<T>::value>> : bind {};
}
demo
How can I create a variadic template function with std::function as a function parameter that accepts a variadic number of arguments? I tried to reduce the problem to a MWE:
#include <functional>
template <class T> void run(std::function<void(T *)> fun, T *obj) { fun(obj); }
template <class T, class... Args>
void run_variadic(std::function<void(T *, Args...)> fun, T *obj, Args... args) {
fun(obj, args...);
}
struct Foo {
void bar() {}
};
int main() {
Foo foo;
std::function<void(Foo *)> fun = &Foo::bar;
run(fun, &foo); // works
run<Foo>(&Foo::bar, &foo); // works
run_variadic(fun, &foo); // works
run_variadic<Foo>(&Foo::bar, &foo); // does not compile
}
It seems like the mere presence of the variadic template parameter in run_variadic makes it impossible to directly call it with a member function pointer. clang's error message is as follows:
main.cpp:21:3: error: no matching function for call to 'run_variadic'
run_variadic<Foo>(&Foo::bar, &foo); // does not compile
^~~~~~~~~~~~~~~~~
main.cpp:6:6: note: candidate template ignored: could not match 'function<void (Foo *, type-parameter-0-1...)>' against 'void (Foo::*)()'
void run_variadic(std::function<void(T *, Args...)> fun, T *obj, Args&&... args) {
^
1 error generated.
Any suggestions on how I can fix run_variadic so that I do not have to go through the extra std::function object?
Background
I have a class hierarchy as
template <class T> class Abstract { ... };
class UnrelatedStuff { ... };
class Derived : public Abstract<UnrelatedStuff> { ... };
There are multiple Derived classes that all have to implement one or more methods to loop over a range of elements. The loop looks something like
#pragma omp parallel for
for (ZFSId i = begin; i != end; ++i) {
callMemFun(i, and, other, args);
}
All loops should be OpenMP-accelerated. I want the accelerator stuff factored out and not repeated in each method of Derived that uses a loop, so that I only have to change one place if e.g. OpenMP would switch to OpenACC.
Thus I am looking for a way to put the loop (and its decoration) in its own function. Moving it to the Abstract base class is not an option either, since the loops are performance-critical and I cannot have an abstract function call in each loop iteration.
You are almost always certainly better off abstracting away the function object:
template <class Functor, class... Args>
void run(Functor&& f, Args&&... args) {
f(std::forward<Args>(args)...);
}
This allows you to do the right thing at call site:
// function object is a lambda that binds to a member function:
run([&](auto... args) { foo.bar(args...); } /*, bar takes no args...*/);
I prefer a lambda to std::function or std::bind but you can also use those if they are already available:
run(std::function<void(Foo *)>{&Foo::bar}, &foo);
run(std::bind(&Foo::bar, &foo));
run(std::mem_fn(&Foo::bar), foo);
I provide a full example program below.
You have now edited the question with new information regarding what you are trying to do.
I'm pretty sure that you don't want to do this, since the OpenMP/OpenACC pragmas like parallel for usually require extra annotations for delivering reasonable performance, and they depend on what you are exactly trying to do at call site.
Still, if you really really want to go this route you can write your own for_each algorithm and dispatch according to an ExecutionAgent (see N3874 and N3731). If OpenMP, TBB, OpenACC parallel task are too slow, you can also easily provide overloads based on e.g. an ExecutionPolicy like this:
template<class RandomAccessRange, class Functor,
class ExecutionPolicy = execution::serial_t>
void for_each(RandomAccessRange&& r, Functor&& f,
ExecutionPolicy&& ex = ExecutionPolicy{}) {
detail::for_each_(std::forward<RandomAccessRange>(r),
std::forward<Functor>(f),
std::forward<ExecutionPolicy>(ex));
}
And then you can implement overloads of for_each_ for each execution policy, e.g.:
namespace detail {
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::serial_t) {
boost::for_each(std::forward<RandomAccessRange>(r), std::forward<Functor>(f));
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::openmp_t) {
#pragma omp parallel for
for (auto&& v : r) { f(v); }
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::openacc_t) {
#pragma acc parallel for
for (auto&& v : r) { f(v); }
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::tbb_t) {
tbb::parallel_for_each(std::begin(std::forward<RandomAccessRange>(r)),
std::end(std::forward<RandomAccessRange>(r)),
std::forward<Functor>(f));
}
} // namespace detail
Note that the ExecutionPolicy is just a tag, i.e.:
namespace execution {
struct serial_t {}; static const constexpr serial_t serial{};
struct openmp_t {}; static const constexpr openmp_t openmp{};
struct openacc_t {}; static const constexpr openacc_t openacc{};
struct tbb_t {}; static const constexpr tbb_t tbb{};
} // namespace execution
This will at least give you an efficient TBB backend even tho the OpenMP/OpenACC performance will be mediocre at best. You can take a look at the parallel implementation of libstdc++ where they use OpenMP. Their for_each algorithm is over 1000 lines of code and uses work-stealing.
Full example program:
#include <functional>
template <class Functor, class... Args>
void run(Functor&& f, Args&&... args) {
f(std::forward<Args>(args)...);
}
struct Foo { void bar() {} };
int main() {
Foo foo;
run([&](auto... args) { foo.bar(args...); } /*, bar takes no args*/);
run(std::function<void(Foo *)>{ &Foo::bar}, &foo);
run(std::bind(&Foo::bar, &foo));
run(std::mem_fn(&Foo::bar), foo);
}
To answer your comment on the previous answer, that answer can be adapted to support pointers to member functions in the way that you've asked for. The previous answer already works for all callable objects, but not directly with a pointer to member function because those are not callable with the usual f(args) syntax. The following version uses tag dispatch to distinguish between pointers to member functions and traditional callable objects, applying the call syntax appropriate to each case.
template <class Functor, class... Args>
void run_helper(std::false_type, Functor f, Args&&... args)
{
f(std::forward<Args>(args)...);
}
template <class Functor, class Arg0, class... Args>
void run_helper(std::true_type, Functor f, Arg0&& arg0, Args&&... args)
{
(std::forward<Arg0>(arg0).*f)(std::forward<Args>(args)...);
}
template <class Functor, class... Args>
void run(Functor f, Args&&... args)
{
run_helper(typename std::is_member_pointer<Functor>::type(),
f, std::forward<Args>(args)...);
}
This can be used in all the same ways as the previous answer could, but also supports directly passing in a pointer to member function:
run(&Foo::bar, foo);
It even works with overloaded member functions and member functions which are templates, if you explicitly instantiate the run template to bind to a particular overloaded function or function template instantiation.
Live example: http://ideone.com/vsBS4H
I have some functions that read various types from serialized data, eg:
class DataDeserializer
{
int getInt();
std::string getString();
MyClass getMyClass();
}
I then have various callback functions that take arbitrary parameters, eg:
void callbackA (int, int, int);
void callbackB (int, std::string);
void callbackC (std::string, int, MyClass, int);
I want to call the various callbacks with arguments read from the deserialized data stream.
What I would like is to automate the boilerplate code as much as possible.
I was thinking maybe I could use templates. If I had some sort of Dispatcher
class, eg:
template <SOMETHING??> class Dispatcher
{
void dispatch()
{
// ????
}
SOMEFUNCTIONTYPE callback;
DataDeserializer myDeserializer;
};
Then declare various specific dispatchers:
Dispatcher<int,int,int> myDispatcherA (deserializer, callbackA);
Dispatcher<int,std::string> myDispatcherB (deserializer, callbackB);
Dispatcher<std::string,int,MyClass,int> myDispatcherC (deserializer, callbackC);
Then when I want to dispatch, I just call:
myDispatcherB.dispatch();
which underneath would expand to something like this:
void dispatch()
{
callback (myDeserializer.getString(), myDeserializer.getInt(), myDeserializer.getMyClass(), myDeserializer.getInt());
}
Is this possible with C++11 variadic templates? I've read up a little on them, and it seems recursion is used a lot.
I have done something similar for my stream_function class. The basic idea is that you pass a type to a function template, which does The Right Thing™, and expand that call:
callback(magic<Args>(/* sth */)...);
However, if your functions aren't pure and modify some state, and as such have the requirement that they need to be called in the correct order, you have to force that order with some tricks.
If you're using Clang, this is rather easy, as it forces left-to-right evaluation for braced-init-lists. This allows you to just use a small helper type
struct invoker{
template<class F, class... Args>
invoker(F&& f, Args&&... args){ f(std::forward<Args>(args)...); }
};
and then do
invoker{ callback, magic<Args>(/* sth */)... };
Unfortunately, GCC doesn't yet implement this feature, so one needs to resort to manual order-enforcement. This can be done with a small helper struct which is just a type-list, but allows one to do some useful things:
see when the pack is empty (types<>), and
process Args in a head-then-tail recursive fashion
template<class...> struct types{};
template<class... Args>
struct dispatcher{
std::function<void(Args...)> f;
void call(){ _call(types<Args...>{}); }
private:
// take head, produce value from it, pass after other values
template<class Head, class... Tail, class... Vs>
void _call(types<Head, Tail...>, Vs&&... vs){
_call(types<Tail...>{}, std::forward<Vs>(vs)..., get_value<Head>());
}
// no more values to produce, forward to callback function
template<class... Vs>
void _call(types<>, Vs&&... vs){ f(std::forward<Vs>(vs)...); }
};
Live example.
Something like this can help you
template<typename T>
T get_value(Deserializer&);
template<>
int get_value(Deserializer& d)
{
return d.getInt();
}
template<>
std::string get_value(Deserializer& d)
{
return d.getString();
}
template<typename... Args>
class Dispatcher
{
public:
template<typename Functor>
Dispatcher(Deserializer& d, const Functor& cb) : myDeserializer(d), callback(cb)
{
}
void dispatch()
{
callback(get_value<Args>(myDeserializer)...);
}
private:
std::function<void(Args...)> callback;
Deserializer myDeserializer;
};
Live example
I have a pretty exotic problem, since I am trying to create some sort of a compiler...
I want to pass a lambda expression to a templated function like this:
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
So that I can now call
bind([&](int a) { // do something });
... So normally, this wouldn't be a problem, since std::function is able to capture a lambda. But here the problem is that (let's assume) I don't know or don't want to provide the info about what "T" is exactly. It could be any function signature you could also insert into std::function<>...
I also need to pass this "inferred" signature back to the "delegate" class I want to return and that delegate class needs to be a pointer to class...
For now I have come up with this:
template<class T>
struct delegate : public std::function<T>
{
delegate(const std::function<T>& func) : std::function<T>(func) { }
delegate(const delegate<T>& func) { }
};
template<class T>
delegate<T>* bind(std::function<T>&& func)
{
return new delegate<T>(std::forward<std::function<T>>(func));
}
But the above example of a call to "bind" fails with "failed template argument deduction". How can I get this to work without having to specify the "T" parameter explicitly when calling "bind" (then it works, at least)?
Since in theory my compiler has all the info to workaround this issue, I could just insert the instance of "T", but this would make the generated code unnecessarily convoluted.
BTW, I am using the lastest Clang compiler.
Here is the final solution:
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
typedef Ret type(Args...);
};
template<class T>
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
return nullptr;
}
Be aware that you may need to adjust the "const" modifiers to your needs.
First, you have completely screwed up your rvalue references. Your forwarding does not work at all.
Secondly, that's impossible in some cases.. For some function objects, you could infer the signature by taking the member function pointer to operator() and inspecting it's signature. But for others, they will be overloaded and it will not work.
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args>
struct get_signature<Ret(Mem::*)(Args...)> {
typedef Ret(Args...) type;
};
template<class T>
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
return nullptr;
}
Thirdly, std::bind?