When compiling the following code:
#include <functional>
template <typename functionSignature>
class Class
{
std::function<functionSignature> func;
public:
Class(const std::function<functionSignature>& arg) : func(arg) {}
void callFunc() { func(); }
};
void f(const int i) {}
int main()
{
Class<void(const int)> a(std::bind(f, 10));
a.callFunc();
return 0;
}
The VS 2015 compiler generates the following error message at the sixth line:
error C2064: term does not evaluate to a function taking 0 arguments.
Now, I believe this is because the compiler thinks functionSignature is not, well, a function signature; the same error happens when I instantiate and try to call operator() on an std::function<int> instead of std::function<int()>, for instance.
How can I guarantee that the template argument will always be a function signature, so that I can call operator() on the std::function?
I suspect you want something like that:
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
std::function<R(P...)> func;
void callFunc(P... p) { func(p...); }
};
By using partial specialization that way you can easily define the type you want.
As an example, you can use it as:
Class<int(double)> c;
Of course, I noticed that you have no constructors for your class, so to invoke func is not a good idea, but it's quite easy to define it and pass a proper function as an argument.
It follows a complete and working example where I've used the operator() to invoke the function:
#include <functional>
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
Class(std::function<R(P...)> f): func{f} { }
void operator()(P... p) { func(p...); }
private:
std::function<R(P...)> func;
};
void fn() { }
int main() {
std::function<void()> f = fn;
Class<void()> c{f};
c();
}
Your error is here:
Class<void(const int)> a(std::bind(f, 10));
The function Class::callFunc() invokes func() -- i.e., no arguments. The result of std::bind(f, 10) is also a function that takes no arguments, which is consistent with the template argument to the class template. Using Class<void(const int)> is inconsistent with both the usage in the class template and the initialization.
The solution is easy: Change the errant line to
Class<void()> a(std::bind(f, 10));
Is this what you are trying to do?
http://ideone.com/fork/IZ0Z1A
If functionSignature is NOT a function, std::function will throw errors when you create Class but you could add a constructor and throw there a static_assert(std::is_function<functionSignature>::value == true," ");if you want I guess.
#include <functional>
#include <iostream>
template <typename functionSignature>
class Class
{
public:
std::function<functionSignature> func;
void callFunc() { func(); }
};
void f()
{
std::cout << "hello" << std::endl;
}
int main()
{
Class<decltype(f)> t {f};
t.callFunc();
return 0;
}
Related
I have a class with a unique_ptr member.
class Foo {
private:
std::unique_ptr<Bar> bar;
...
};
The Bar is a third party class that has a create() function and a destroy() function.
If I wanted to use a std::unique_ptr with it in a stand alone function I could do:
void foo() {
std::unique_ptr<Bar, void(*)(Bar*)> bar(create(), [](Bar* b){ destroy(b); });
...
}
Is there a way to do this with std::unique_ptr as a member of a class?
Assuming that create and destroy are free functions (which seems to be the case from the OP's code snippet) with the following signatures:
Bar* create();
void destroy(Bar*);
You can write your class Foo like this
class Foo {
std::unique_ptr<Bar, void(*)(Bar*)> ptr_;
// ...
public:
Foo() : ptr_(create(), destroy) { /* ... */ }
// ...
};
Notice that you don't need to write any lambda or custom deleter here because destroy is already a deleter.
It's possible to do this cleanly using a lambda in C++11 (tested in G++ 4.8.2).
Given this reusable typedef:
template<typename T>
using deleted_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;
You can write:
deleted_unique_ptr<Foo> foo(new Foo(), [](Foo* f) { customdeleter(f); });
For example, with a FILE*:
deleted_unique_ptr<FILE> file(
fopen("file.txt", "r"),
[](FILE* f) { fclose(f); });
With this you get the benefits of exception-safe cleanup using RAII, without needing try/catch noise.
You just need to create a deleter class:
struct BarDeleter {
void operator()(Bar* b) { destroy(b); }
};
and provide it as the template argument of unique_ptr. You'll still have to initialize the unique_ptr in your constructors:
class Foo {
public:
Foo() : bar(create()), ... { ... }
private:
std::unique_ptr<Bar, BarDeleter> bar;
...
};
As far as I know, all the popular c++ libraries implement this correctly; since BarDeleter doesn't actually have any state, it does not need to occupy any space in the unique_ptr.
Unless you need to be able to change the deleter at runtime, I would strongly recommend using a custom deleter type. For example, if use a function pointer for your deleter, sizeof(unique_ptr<T, fptr>) == 2 * sizeof(T*). In other words, half of the bytes of the unique_ptr object are wasted.
Writing a custom deleter to wrap every function is a bother, though. Thankfully, we can write a type templated on the function:
Since C++17:
template <auto fn>
struct deleter_from_fn {
template <typename T>
constexpr void operator()(T* arg) const {
fn(arg);
}
};
template <typename T, auto fn>
using my_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
// usage:
my_unique_ptr<Bar, destroy> p{create()};
Prior to C++17:
template <typename D, D fn>
struct deleter_from_fn {
template <typename T>
constexpr void operator()(T* arg) const {
fn(arg);
}
};
template <typename T, typename D, D fn>
using my_unique_ptr = std::unique_ptr<T, deleter_from_fn<D, fn>>;
// usage:
my_unique_ptr<Bar, decltype(&destroy), destroy> p{create()};
You know, using a custom deleter isn't the best way to go, as you will have to mention it all over your code.
Instead, as you are allowed to add specializations to namespace-level classes in ::std as long as custom types are involved and you respect the semantics, do that:
Specialize std::default_delete:
template <>
struct ::std::default_delete<Bar> {
default_delete() = default;
template <class U>
constexpr default_delete(default_delete<U>) noexcept {}
void operator()(Bar* p) const noexcept { destroy(p); }
};
And maybe also do std::make_unique():
template <>
inline ::std::unique_ptr<Bar> ::std::make_unique<Bar>() {
auto p = create();
if (!p)
throw std::runtime_error("Could not `create()` a new `Bar`.");
return { p };
}
You can simply use std::bind with a your destroy function.
std::unique_ptr<Bar, std::function<void(Bar*)>> bar(create(), std::bind(&destroy,
std::placeholders::_1));
But of course you can also use a lambda.
std::unique_ptr<Bar, std::function<void(Bar*)>> ptr(create(), [](Bar* b){ destroy(b);});
#include "fmt/core.h"
#include <memory>
class example {};
void delete_example(example *)
{
fmt::print("delete_example\n");
}
using example_handle = std::unique_ptr<example, decltype([] (example * p)
{
delete_example(p);
})>;
int main()
{
example_handle handle(new example);
}
Just my two cents, using C++20.
https://godbolt.org/z/Pe3PT49h4
With a lambda you can get the same size as a plain std::unique_ptr. Compare the sizes:
plain: 8
lambda: 8
fpointer: 16
std::function: 40
Which is the output of the following. (I declared the lambda outside the scope of the class. Not sure if you can scope it inside the class.)
#include <iostream>
#include <memory>
#include <functional>
struct Bar {};
void destroy(Bar* b) {}
Bar* create() { return 0; }
auto lambda_destroyer = [](Bar* b) {destroy(b);};
class Foo {
std::unique_ptr<Bar, decltype(lambda_destroyer)> ptr_;
public:
Foo() : ptr_(create(), lambda_destroyer) { /* ... */ }
};
int main()
{
std::cout << "plain: " << sizeof (std::unique_ptr<Bar>) << std::endl
<< "lambda: " << sizeof (std::unique_ptr<Bar, decltype(lambda_destroyer)>) << std::endl
<< "fpointer: " << sizeof (std::unique_ptr<Bar, void(*)(Bar*)>) << std::endl
<< "std::function: " << sizeof (std::unique_ptr<Bar, std::function<void(Bar*)>>) << std::endl;
}
I'm fairly convinced that this is the best current way to do it:
#include <memory>
#include <stdio.h>
template <typename T, auto fn>
struct Deleter
{
void operator()(T *ptr)
{
fn(ptr);
}
};
template <typename T, auto fn>
using handle = std::unique_ptr<T, Deleter<T, fn>>;
using file = handle<FILE, fclose>;
int main()
{
file f{fopen("a.txt", "w")};
return 0;
}
Because you've specified a Functor as the deleter in the unique_ptr's template arguments, you don't need to set a deleter when calling its constructor.
The Deleter functor uses "template auto" to take a deletion function (in this example: fclose) as a template argument, so this needs C++17.
Expanding it to support other types is just one extra "using" line per type.
Simple is also:
class Foo {};
class Bar
{
public:
Bar()
{
// actual initialisation at some point
}
private:
std::unique_ptr<Foo, void(*)(Foo*)> foo = {{}, {}}; // or = {nullptr, {}}
};
Sure, you can also create some helper function to do the job to not have the initial state at any time.
In fact, in your specific scenario, the cleanest way is to actually put your Bar (not mine, sorry for the confusion) into a simple wrapper class, which makes reuse easier.
I have a C++ problem. I want to generate a type based on the type arguments passed to a templated function of it.
Let me illustrate it.
class A {
template<class B> M() { }
void Z() {
// NOTE: Here I want to call to X on each type that was feed it to M.
X<N1>();
X<N1>();
...
X<NN>();
}
template<class B> X() { }
};
For example
A a;
a.M<int>();
a.M<double>();
then a.Z() executes ...
X<int>();
X<double>();
Another example to take into account unique types
A a;
a.M<int>();
a.M<int>();
a.M<double>();
a.M<double>();
then a.Z() will still executes ...
X<int>();
X<double>();
Note that I am generating the type A based on the calls to M.
OK! I think that for that class A that's conceptually impossible because A is not templated type and then it can not vary in that way, In fact that's not possible for any type in C++ (I think). But I want you to get the idea.
I am looking forward for a way to confront this problem using meta-programming, but any advice or solution or reference is welcome.
No metaprogramming needed.
class A {
using XPtr = void (A::*)();
std::vector<XPtr> x_calls;
std::set<std::type_index> x_types;
template <typename B> void X() { ... }
public:
template <typename B> void M() {
bool is_new = x_types.insert(std::type_index(typeid(B))).second;
if (is_new)
x_calls.push_back(&A::X<B>);
...
}
void Z() {
for (auto&& ptr : x_calls) {
(this->*ptr)();
}
}
};
First off, I think you're interface isn't really MPL. To be MPL you'd call it more like typedef MyType mpl::vector<int, double> and then find a way to build a type that called X<...> for each type. However...
#include <iostream>
#include <typeinfo>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template< typename T>
void X() {
cout<<typeid(T).name()<<endl;
}
struct A {
vector< function<void(void)> > callbacks;
void z() {
for( auto a : callbacks ) a();
}
template<typename T>
void M() {
callbacks.push_back( [](){ X<T>();} );
}
};
int main() {
A a;
a.M<int>();
a.M<double>();
a.z();
return 0;
}
does what you want.
$ g++ --std=c++11 && ./a.out
i
d
Ss
See it live
You can achieve similar functionality using boost::fusion::set and boost::mpl.
class A {
struct functoid {
template<typename T>
void operator(T t)
{
/* do something */
}
}
template<class B> M() {
boost::mpl::for_each<B>(functoid());
}
}
A a;
a.template M<boost::fusion::set<int, double, ...>>();
But, in this case, you need to know the actual types, or, register some callback in operator().
I'm trying to implement simple ScopedExit class. Here's the code:
#include <iostream>
#include <functional>
template<class R, class... Args>
class ScopedExit
{
public:
ScopedExit(std::function<R(Args...)> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<R(Args...)> exitFunc_;
};
template<>
class ScopedExit<void>
{
public:
ScopedExit(std::function<void ()> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void ()> exitFunc_;
};
void foo()
{
std::cout << "foo() called\n";
}
class Bar
{
public:
void BarExitFunc(int x, int y)
{
std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
}
};
int main()
{
Bar b;
std::cout << "Register scoped exit func\n";
{
ScopedExit<void, int, int> exitGuardInner(std::bind(&Bar::BarExitFunc, &b, 18, 11));
}
ScopedExit exitGuardOutter(foo);
std::cout << "About to exit from the scope\n";
return 0;
}
So, there are a couple of questions:
How to pass exit's function arguments to it? For example, I bind BarExitFunc with two integer arguments: 18 and 11. So how can I pass it to the exitFunc_ in the destructor? I think I need something like invoke function with std::forward<>.
gcc 4.7.2 (from ideone.com) complains about exitGuardOutter. It says:
prog.cpp:60:16: error: missing template arguments before ‘exitGuardOutter’
prog.cpp:60:16: error: expected ‘;’ before ‘exitGuardOutter’
Thanks in advance.
How to pass exit's function arguments to it? For example, I bind BarExitFunc with two integer arguments: 18 and 11. So how can I pass it to the exitFunc_ in the destructor?
I can see no reason whatsoever to pass arguments to exitFunc_ at call time in the destructor. Whatever you do, you'll have to provide those arguments upfront in the ScopedExit constructor anyway.
The most straightforward way is simply to use a function<R()> and bind any required arguments at the definition site like you're already doing:
ScopedExit<R> guard(std::bind(someFunction, someArg, otherArg));
This allows you to get rid of the variadic template arguments altogether and simplifies your template a lot.
Now, if what is bothering you is that you have to type std::bind and you would rather use such a syntax:
ScopedExit<R> guard(someFunction, someArg, otherArg);
Really, I don't see the point since it makes the template more complicated, but why not... Just bind/forward the arguments in the constructor itself and still store a function<R()>:
template<typename... Args>
ScopedExit(std::function<R(Args...)> exitFunction, Args&&... args)
{
exitFunc_ = std::bind(exitFunction, std::forward<Args>(args)...);
}
Now you systematically bind the function even if there are no arguments to bind, so you may want to specialize your class to avoid this useless bind when there are no arguments. This is left as an exercise.
gcc 4.7.2 (from ideone.com) complains about exitGuardOutter
This is because foo isn't a std::function and the compiler can't deduce the correct template arguments. As already mentioned by #ForEveR you could just define your guard variable as ScopedExit<void> guard(foo);.
Or, wrapping it all up and keeping in mind what I first said (bind is best left out of your template and used at the definition site of your guard) you could just get rid of std::function in the constructor and generalize for any functor (which, BTW, is how the Standard library does whenever it needs a functor/callback). For storage you can just use std::function<void()> since it accepts non-void return types too:
class ScopedExit
{
public:
template<typename Functor>
ScopedExit(Functor exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void()> exitFunc_;
};
int foo() { return 0; }
struct Bar {
void bye(int, int) {}
};
struct Baz {
void operator ()() {}
};
int main() {
const std::string what = "lambda!";
ScopedExit guard1([&]() { std::cout << "yay a " << what << std::endl; });
ScopedExit guard2(foo); // note how std::function<void()> accepts non-void return types
Bar b;
ScopedExit guard3(std::bind(&Bar::bye, &b, 1, 2));
ScopedExit guard4(Baz());
}
Note how your original variadic template class has now become a flexible non-template class with just a templated constructor whose template argument is deduced automatically, and which accepts almost[see note below] any kind of functor you can think about.
Note: I said almost any functor because this doesn't work with default arguments:
void foobar(int = 0) {}
ScopedExit guard5(foobar); // error: too few arguments to function
Even if you stored a Functor directly instead of a std::function<void()> you wouldn't be able to make use of the default arguments anyway (the signature of foobar is still void(int) even with a default argument) so one always has to handle this corner-case at the definition site with something like:
void foobar(int = 0) {}
ScopedExit guard5([]() { foobar(); });
1) You can save arguments in tuple for example. However, in your case, you can simply call exitFunc_() and function definition should be std::function<R()> exitFunction since you already bind arguments to function. Something like this probably
#include <iostream>
#include <functional>
#include <tuple>
template<size_t...>
struct indices {};
template<size_t N, size_t... Is>
struct gen_indices : gen_indices<N - 1, N - 1, Is...>
{
};
template<size_t... Is>
struct gen_indices<0, Is...> : indices<Is...>
{
};
template<class R, class... Args>
class ScopedExit
{
public:
ScopedExit(std::function<R(Args...)> exitFunction, Args&&... args)
: arguments_(std::forward_as_tuple(args...))
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
call(gen_indices<sizeof...(Args)>());
}
private:
template<size_t... Idx>
void call(indices<Idx...>)
{
exitFunc_(std::forward<Args>(std::get<Idx>(arguments_))...);
}
std::tuple<Args...> arguments_;
std::function<R(Args...)> exitFunc_;
};
template<>
class ScopedExit<void>
{
public:
ScopedExit(std::function<void ()> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void ()> exitFunc_;
};
void foo()
{
std::cout << "foo() called\n";
}
class Bar
{
public:
void BarExitFunc(int x, int y)
{
std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
}
};
int main()
{
Bar b;
std::cout << "Register scoped exit func\n";
{
ScopedExit<void, int, int> exitGuardInner
(
std::bind(&Bar::BarExitFunc, &b, std::placeholders::_1,
std::placeholders::_2), 10, 18
);
}
ScopedExit<void> exitGuardOutter(foo);
std::cout << "About to exit from the scope\n";
return 0;
}
2) Should be created like ScopedExit<void>.
Say I'm using a C API that lets you register callbacks that take a void* closure:
void register_callback(void (*func)(void*), void *closure);
In C++ it's nice to have stronger types than void* so I want to create a wrapper that lets me register strongly-typed C++ callbacks instead:
template <typename T, void F(T*)>
void CallbackWrapper(void *p) {
return F(static_cast<T*>(p));
}
void MyCallback(int* param) {}
void f(void *closure) {
register_callback(CallbackWrapper<int, MyCallback>, closure);
}
This works alright. One nice property of this solution is that it can inline my callback into the wrapper, so this wrapping scheme has zero overhead. I consider this a requirement.
But it would be nice if I could make the API look more like this:
void f2() {
RegisterCallback(MyCallback, closure);
}
I hope I can achieve the above by inferring template parameters. But I can't quite figure out how to make it work. My attempt so far is:
template <typename T>
void RegisterCallback(void (*f)(T*), T* closure) {
register_callback(CallbackWrapper<T, f>, closure);
}
But this doesn't work. Anyone have a magic incantation that will make f2() work above, while retaining the zero-overhead performance characteristic? I want something that will work in C++98.
This template function improves the syntax marginally.
template <typename T, void F(T*)>
void RegisterCallback (T *x) {
register_callback(CallbackWrapper<T, F>, x);
}
int x = 4;
RegisterCallback<int, MyCallback>(&x);
If you are willing to use a functor rather than a function to define your callback, then you can simplify things a bit more:
#ifdef HAS_EXCEPTIONS
# define BEGIN_TRY try {
# define END_TRY } catch (...) {}
#else
# define BEGIN_TRY
# define END_TRY
#endif
template <typename CB>
void CallbackWrapper(void *p) {
BEGIN_TRY
return (*static_cast<CB*>(p))();
END_TRY
}
struct MyCallback {
MyCallback () {}
void operator () () {}
};
template <typename CB>
void RegisterCallback (CB &x) {
register_callback(CallbackWrapper<CB>, &x);
}
MyCallback cb;
RegisterCallback(cb);
But, as others have mentioned, you run the risk of the code not porting correctly to a system where the C ABI and C++ ABI differ.
I have discovered a better answer to this question than the other answers given to me here! (Actually it was another engineer inside Google who suggested it).
You have to repeat the function name twice, but that can be solved with a macro.
The basic pattern is:
// Func1, Func2, Func3: Template classes representing a function and its
// signature.
//
// Since the function is a template parameter, calling the function can be
// inlined at compile-time and does not require a function pointer at runtime.
// These functions are not bound to a handler data so have no data or cleanup
// handler.
template <class R, class P1, R F(P1)>
struct Func1 {
typedef R Return;
static R Call(P1 p1) { return F(p1); }
};
// ...
// FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function
// *signature*, but without a specific function attached.
//
// These classes contain member functions that can be invoked with a
// specific function to return a Func/BoundFunc class.
template <class R, class P1>
struct FuncSig1 {
template <R F(P1)>
Func1<R, P1, F> GetFunc() { return Func1<R, P1, F>(); }
};
// ...
// Overloaded template function that can construct the appropriate FuncSig*
// class given a function pointer by deducing the template parameters.
template <class R, class P1>
inline FuncSig1<R, P1> MatchFunc(R (*f)(P1)) {
(void)f; // Only used for template parameter deduction.
return FuncSig1<R, P1>();
}
// ...
// Function that casts the first parameter to the given type.
template <class R, class P1, R F(P1)>
R CastArgument(void *c) {
return F(static_cast<P1>(c));
}
template <class F>
struct WrappedFunc;
template <class R, class P1, R F(P1)>
struct WrappedFunc<Func1<R, P1, F> > {
typedef Func1<R, void*, CastArgument<R, P1, F> > Func;
};
template <class T>
generic_func_t *GetWrappedFuncPtr(T func) {
typedef typename WrappedFunc<T>::Func Func;
return Func().Call;
}
// User code:
#include <iostream>
typedef void (generic_func_t)(void*);
void StronglyTypedFunc(int *x) {
std::cout << "value: " << *x << "\n";
}
int main() {
generic_func_t *f = GetWrappedFuncPtr(
MatchFunc(StronglyTypedFunc).GetFunc<StronglyTypedFunc>());
int x = 5;
f(&x);
}
This is not short or simple, but it is correct, principled, and standard-compliant!
It gets me what I want:
The user gets to write StronglyTypedFunc() taking a pointer to a specific thing.
This function can be called with a void* argument.
There is no virtual function overhead or indirection.
Why not make your closure a real closure (by including real typed state).
class CB
{
public:
virtual ~CB() {}
virtual void action() = 0;
};
extern "C" void CInterface(void* data)
{
try
{
reinterpret_cast<CB*>(data)->action();
}
catch(...){}
// No gurantees about throwing exceptions across a C ABI.
// So you need to catch all exceptions and drop them
// Or probably log them
}
void RegisterAction(CB& action)
{
register_callback(CInterface, &action);
}
By using an object you can introduce real state.
You have a clean C++ interface with correctly types objects.
Its easy to use you just derive from CB and implement action().
This also has the same number of actual function calls as you use. Because in your example you pass a function pointer to the wrapper (which can't be inlined (it can but it will take more static analysis then current compilers do)).
Apparently it does inline.
When I want to have member function as template argument, is there a way to templetize it without providing Caller type?
struct Foo
{
template <typename Caller, void (Caller::*Func)(int)>
void call(Caller * c) { (c->*Func)(6); }
};
struct Bar
{
void start()
{
Foo f;
f.call<Bar, &Bar::printNumber>(this);
^^^^
}
void printNumber(int i) { std::cout << i; }
};
int main ()
{
Bar b;
b.start();
return 0;
}
when I try
template <void (Caller::*Func)(int), typename Caller>
void call(Caller * c) { (c->*Func)(6); }
and call it like
f.call<&Bar::printNumber>(this);
I am getting Caller is not class... error.
So, is there a way to let compiler deduce the Caller type?
No, not as you want it. Caller could be deduced if
the pointer to member function were an parameter, not a template parameter. Eg:
template <class Caller>
void call(Caller * c, void (Caller::*Func)(int)) { (c->*Func)(6); }
it was known beforehand. For example, you could make the call look like this:
f.arg(this).call<&Bar::printNumber>();
The call function would look similar to this:
template <class Arg>
struct Binder
{
template<void (Arg::*Func)(int)>
void operator()() const {
...
}
};
The arg function would be easy to write (in your case it would return Binder<Bar>, where Bar is deduced from this).
Not very convenient, IMHO.