Variadic Function That Calls Constructor With Given Arguments - c++

Need to create variadic template<T> function with different arg types that will call constructor of T with given arguments, sort of like when creating a thread but reverse (when creating a thread, its constructor calls function at given funct pointer).
So in pseudo code it should look something like this
template<typename T>
T* CreateNew( ARGS ) {
return new T( ARGS ); //Constructor Gets Same Arguments That Were
} //Passed To The Function
Want this to behave like when creating threads, when they call functions with their arguments that are of different types (which I am unsure how to achive).

Its not entirely clear to me but I think you want to look up variadic templates, e.g.:
template <typename T, typename... Args>
T* CreateNew(Args... args) {
return new T(args...);
}
Adding Example:
#include <iostream>
class A {
public:
A(int a){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
A(std::string a){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
A(int a,std::string b){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
};
template<typename T, typename... Args>
T* create(Args... args){
return new T(args...);
}
int main(){
A b(1);
A c("a");
A d(1,"a");
A* bp = create<A>(1);
A* cp = create<A>("a");
A* dp = create<A>(1,"a");
// This code leaks
return 0;
}
Note that because the changes are kept as minimal as possible, we still return a T* here as the original code. Most of the time, this is not a good idea since ownership is passed via raw pointers. Therefore, as suggested by the comments, you might want to use a std::unique_ptr, which would make your CreateNew function basically equivalent to std::make_unique.

The correct way to write this function is
template <typename T, typename... Args>
T* CreateNew(Args&&... args) {
return new T(std::forward<Args>(args)...);
}
Without the forwarding reference Args&& and without std::forward, the original value categories of the passed arguments will not be propagated to T's constructor, causing potential performance and semantic problems.

Related

How to convert a constructor to a std::function [duplicate]

This question already has answers here:
How to pass a function pointer that points to constructor?
(8 answers)
Construct std::function with a constructor based on template
(1 answer)
Closed 3 years ago.
Is there any way to assign a constructor to a function like 'f':
struct C
{
C(int){};
};
auto f = C::C(int); // not work
auto g = [](int){ return C(int()); }; // works
Neither C, C::C, &C, &C::C, C::&C, C::C(int), &C::C(int) ... works
Solution proposed by Friday Pie:
template <class T>
struct ConstructHelper
{
template <class... Args>
static T&& construct(Args&&... args)
{
return std::move(T(std::forward<Args>(args)...));
}
};
auto f = ConstructHelper<C>::construct<int>; // works
auto c = apply(f, 0); // works
The code you tried to write follows other rules than than the lambda that you wrote.
In the first one, you are trying to get a pointer to a member function: &C::C This would be similar to &C::print (assuming argument int) The first argument of this function would be a pointer to C, the second would the the int.
However, we are trying to do this for the constructor. So we don't have a valid C to work on. The result is that this simply doesn't compile.
Note that if you do want to execute a constructor on existing memory, you need placement new.
Your second code is a lambda. In short: a class with operator() implemented. And in this operator, you write code as in any other function and return a newly constructed instance by value. (Although, this looks a lot like a vexing parse) Tis is similar to executing the print function that was mentioned before.
So both would have different semantics and your compiler is right in failing to compile this code.
In theory your hypothetical function apply would look quite simple as a template
#include <iostream>
#include <type_traits>
struct C
{
C(int){};
};
template <class F, class... Args>
auto apply ( F&& f, Args&&... args) -> typename std::result_of<F(Args...)>::type
{
return f(args...);
}
float foo (int a, float b) { return a*b; }
int main()
{
auto b = apply(&foo, 3, 5.f);
//auto b = apply(&C::C, 3); //error: taking address of constructor 'C::C'
return 0;
}
But it is impossible to take address of constructor, as per the ISO standard. In most cases this special function is a non-entity in resulting code.
Neither explicit call to constructor is allowed. Your lambda function does thing differently. It constructs an object of class C as to per defined effect of that expression.
You could use a bogus argument and SFINAE
template <class F, class... Args>
auto apply ( F&& f, Args&&... args)
-> std::enable_if_t<std::is_invocable<F, Args...>::value,
typename std::result_of<F(Args...)>::type>
{
return f(args...);
}
template <class T, class... Args>
auto apply ( T&&, Args&&... args)
-> std::enable_if_t<!std::is_invocable<T, Args...>::value,T&&>
{
return std::move(T(args...));
}
but it's preferable to avoid that and rethink whatever meta-programming pattern you have in mind, i.e. avoid attempt to call same template name for different kinds of arguments, or make amends with lambda use. E.g. you may avoid to call apply() by using SFINAE.

Template Deduction of Base Template Parameters through Smart Pointers and Conversion

See Compiler Explorer for a full example: https://godbolt.org/z/_rVFvO
Given an abstract template class Runnable and an implementation Derived inheriting from Runnable<int>:
#include <iostream>
#include <memory>
using namespace std;
template<class... Args>
struct Runnable
{
virtual ~Runnable() = default;
virtual void f(Args... args) const = 0;
};
struct Derived : public Runnable<int>
{
void f(int x) const override
{
cout << "f(" << x << ")" << endl;
}
};
What is the underlying reason the template parameter deduction for the function accept_variadic fails given the smart pointer to a derived type?
template<class... Args>
void accept_variadic(std::unique_ptr<Runnable<Args...>> o, Args&&... args)
{
o->f(forward<Args>(args)...);
}
int main()
{
accept_variadic(make_unique<Derived>(), 5); // Error (no conversion)
return 0;
}
But given a reference (or pointer) directly without a smart pointer works:
template<class... Args>
void accept_variadic_ref(const Runnable<Args...>& o, Args&&... args)
{
o.f(forward<Args>(args)...);
}
int main()
{
accept_variadic_ref(Derived(), 5); // OK
return 0;
}
Also, is there a way to support a similar usage with template class deduction guides or using a different smart pointer (owning raw pointers and non lifetime extending references would be difficult in my application).
Instead of:
template<class... Args>
void accept_variadic(std::unique_ptr<Runnable<Args...>> o, Args&&... args)
{
o->f(forward<Args>(args)...);
}
You can use TMP to get what you want:
template<class T, class... Args>
std::enable_if_t<std::is_convertible_v<std::unique_ptr<T>,
std::unique_ptr<Runnable<Args...>>>>
accept_variadic(std::unique_ptr<T> o, Args&&... args)
{
o->f(forward<Args>(args)...);
}
(See full code here)
This is not 100% equivalent, since the propose solution accepts a std::unique_ptr of the Derived type, while the original code will accept only the base type.
The original code does not work, since the templates do to match types that require conversion. In your code, the two std::unique_ptr types are not base/derived of each other, so the templates won't match.
With the proposed solution, the function accepts the original std::unique_ptr, provided that it can be converted to the base type inside the function. The std::enable_if_t makes sure that other types don't match, only the ones that can be converted to the base.
Edit
In some variants of the question, the original solution could be problematic. This can happen in question variants in which calling f() on a base class is treated differently than calling f() on the derived class. There are several possibilities when this can happen (but not in the original question). To overcome this risk, accept_variadic() should be altered to:
template<class T, class... Args>
std::enable_if_t<std::is_convertible_v<T&, Runnable<Args...>&>>
accept_variadic(std::unique_ptr<T> o, Args&&... args)
{
// could also be solved with
// std::unique_ptr<Runnable<Args...>> base = std::move(o);
Runnable<Args...> & runnable = *o;
runnable.f(forward<Args>(args)...);
}

How to make constructor accepting std::function also accept method pointers

Say I have
class Foo
{
public:
Foo(std::function<void(std::string)> callback1,
std::function<void(int)> callback2) :
callback1(callback1), callback2(callback2)
{
}
private:
std::function<void(std::string)> callback1;
std::function<void(int)> callback2
}
I can easily construct it in the case I'm using plain functions
void callback1Handler(std::string)
{
// i'm a potato
}
void callback2Handler(int)
{
// i'm a teapot
}
int main()
{
Foo foo(callback1Handler, callback2Handler);
return 0;
}
But if I'm using a class, then things get complicated.
I'd like to be able to do something like the Addendum of this answer does
class Main
{
public:
Main()
{
Foo foo(&Main::callback1Handler, &Main::callback2Handler);
}
void callback1Handler(std::string)
{
// i'm a potato
}
void callback2Handler(int)
{
// i'm a teapot
}
}
But that obviously wouldn't compile. To make it work one would need to use either std::bind or lambdas, or something else.
I want to try to avoid the ugliness of std::bind(&Main::callbackNHandler, this, std::placeholders::_1, ..., std::placeholders::_N), which is mostly the ugliness of having those placeholders explicitly specified.
Using lambdas as [=](std::string str){callbackNHandler(str);} is also ugly, because you have to specify every single variable the callback accepts.
It would be great if I could just use &Main::callback1Handler, just like in the Main class example, or &Main::callback1Handler, this, which is a bit more flexible, since you can specify the instance pointer of Main.
Note that Foo constructor has to remain the same and callback1&callback2 member variables have to also remain the same. However, you may overload Foo constructor, making the overload convert method pointers (or whatever else you will make it to accept) into std::functions and store them in callback1&callback2.
template<class T, class R, class...Args>
std::function<R(Args...)> method( T* t, R(T::*m)(Args...) ){
return [=](Args&&...args)->R{
return (t->*m)(std::forward<Args>(args)...);
};
}
then method( instance, &Main::callback1Handler ) should work, up to typos.
It gets simpler in C++14.
The above does needless type erasure: a helper type instead of a lambda lets you avoid that.
template<class T, class Sig>
struct method_t;
template<class T, class R, class... Args>
struct method_t<T,R(Args...)> {
T* t;
R(T::*m)(Args...);
template<class...Ts>
R operator()(Ts&&...ts)const{
return (t->*m)(std::forward<Ts>(ts)...);
}
};
template<class T, class R, class...Args>
method_t<T, R(Args...)> method( T* t, R(T::*m)(Args...) ){
return {t, m};
}
with the same signature. It can even be stored in a std::function<R(Args...)>. The advantage of the above is that there is no needless overhead if the signature of the std::function does not exactly match, or if you don't use a std::function at all.
The downside is 3x as much code.
In C++14 we can simply do:
template<class T, class R, class...Args>
auto method( T* t, R(T::*m)(Args...) ){
return [=](auto&&...args)->R{
return (t->*m)(decltype(args)(args)...);
};
}
which is as brief as the first one, and as powerful as the second one.
Using lambdas as [=](std::string str){callbackNHandler(str);} is also ugly, because you have to specify every single variable the callback accepts.
C++14 generic lambdas solve that problem:
[this](auto... args){ callback1Handler(args...); }
For C++11 you could write a simple utility that can be used like so:
Foo foo(simple_bind(&Main::callback1Handler, this),
simple_bind(&Main::callback2Handler, this));
That would be defined as a function template like this:
template<typename T, typename F>
SimpleBinder<T, F>
simple_bind(F T::* memfn, T* that)
{ return { that, memfn }; }
Where the type SimpleBinder<T, F> is just:
template<typename T, typename F>
struct SimpleBinder
{
T* m_this;
F T::* m_memfn;
template<typename... Args>
void operator()(Args&&... args)
{ (m_this->*m_memfn)(std::forward<Args>(args)...); }
};
This isn't a fully generic utility (for example, it doesn't do anything with the return type of the member function, always returning void, but that is OK for your requirements, where both the std::function objects return void anyway), but it solves the problem of associating an arbitrary member function with a this pointer, and then calling it with some set of arguments.
Although the SimpleBind object appears to accept any arguments, in fact you'll get a nasty compiler error if you try to call it with arguments that aren't compatible with the member function it binds. Again, that's not a problem, because the std::function objects you store it in will ensure that only the right type of arguments are ever passed to it.

Undefined argument list

I have a C++ template class (in Qt) that should handle a list of custom items. This class has a simple member function that is supposed to call the constructor of the template type and add the created item to the list.
void CustomList::addElement(void)
{
T *element = new T();
// ...
}
But I have a problem : I'd like this function to be able to call overloaded constructors.
I thought I could give it the arguments that should be used in the constructor. So it would be called with as arguments a "copy" of the arguments given to addElement().
Except that I don't know how many of them there are, no more than their types. Any simple way I could do it ?
So it would be called with as arguments a "copy" of the arguments
given to addElement().
Why copies when you can use the original arguments?
With C++11 you can use variadic templates and perfect forwarding:
template <typename... Args>
void CustomList::addElement(Args&&... args)
{
T *element = new T(std::forward<Args>(args)...);
// ...
}
Without proper C++11 support you will have to overload the addElement function (template) for every amount of arguments until a sensible limit is reached. I.e.
template <typename Arg1>
void CustomList::addElement(Arg1 const& arg1)
{
T *element = new T(arg1);
// ...
}
template <typename Arg1, typename Arg2>
void CustomList::addElement(Arg1 const& arg1, Arg2 const& arg2)
{
T *element = new T(arg1, arg2);
// ...
}
// [...]

How to create a variadic template function with `std::function` as a function parameter?

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