Somebody can help me to build this source code in a right way,
I understand that I shold declare the callBack as std::function<void(std::unique_ptr<int>&& param)> because this take a no copy
constructible param(std::unique_ptr), so what is the correct type if I no use auto to deduce the type?
#include <functional>
#include <memory>
template <class T>
class SomeClass {
void someFunctionCallback(float o) = 0;
};
template <>
class SomeClass<float> {
public:
SomeClass() = default;
inline void someFunction() {
// std::function<void()>
auto callBack {
std::move(std::bind(&SomeClass<float>::someFunctionCallback,
this,
std::unique_ptr<int>{new int(9)}))};
useCallBack(std::move(callBack));
}
inline void someFunctionCallback(std::unique_ptr<int>&& param) {
}
inline void useCallBack(std::function<void()> &&callBack) {
// callBack();
}
};
int main() {
SomeClass<float> k;
k.someFunction();
return 0;
}
Your code has a couple of problems. First, auto { ... } will deduce an std::initializer_list. That's not what you want. Use a brace-or-equal initializer instead.
auto callBack =
std::bind(&SomeClass<float>::someFunctionCallback,
this,
std::unique_ptr<int>{new int(9)});
Second, your function takes an rvalue-reference, but std::bind will pass an lvalue. Read Passing rvalues through std::bind for a full explanation, but as a workaround you can use this ugly cast:
using uptr = std::unique_ptr<int>;
auto callBack =
std::bind(&SomeClass<float>::someFunctionCallback,
this,
std::bind(static_cast<uptr&&(&)(uptr&)>(std::move<uptr&>),
std::unique_ptr<int>{new int(9)})
) ;
Finally, just make your function a template. The whole idea is not to worry about the type, and auto follows the rules of template argument deduction anyway.
template <typename T>
inline void useCallBack(T callBack) {
callBack();
}
Related
I want to make for_each function for 2D-vector but there is an error:
error: no matching function for call to ‘each(std::vector<std::vector<int> >&, main()::<lambda(int&)>)’
How can I fix it?
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
template <class VarType>
void each(vector<vector<VarType>> &ve, function<void (VarType &)> action) {
for(vector<VarType> &v : ve) {
for(VarType &p : v) {
action(p);
}
}
}
int main() {
vector<vector<int>> map(5);
for(vector<int> &ve : map) {
ve.resize(4);
}
each(map, [](int &val) {
val = 1;
});
}
There are a few solutions. I would recommend to just go for a separate template parameter for the function:
template <class VarType, class Function>
void each(vector<vector<VarType>> &ve, Function action) {
// no more worries
}
The problem is that the compiler cannot figure out the VarType in function<void (VarType&)> from the passed lambda. So doing:
function<void(int&)> action = [](int &val) {
val = 1;
};
each(map, action);
would also work, since this way the type (int&) is already known.
P.S. In C++17 you can do std::function action = [](int &val) { val = 1; };.
While I think taking the function as another template parameter as suggested by #DeiDei is the better solution, here is an alternative:
If you want VarType to be deduced from the first function parameter, then you can make the second parameter a non-deduced context:
template <class VarType>
void each(vector<vector<VarType>> &ve,
typename type_identity<function<void (VarType &)>>::type action) {
for(vector<VarType> &v : ve) {
for(VarType &p : v) {
action(p);
}
}
}
This requires C++20 for std::type_identity and #include<type_traits>, but you can implement your own type_identity easily:
template<typename T>
struct type_identity {
using type = T;
};
This works because everything left to the scope resolution operator :: is a non-deduced context, meaning that the template parameters in it will not be deduced from this function parameter. Your original function fails template argument deduction, because VarType cannot be deduced from the second parameter as the second function argument given in the call does not actually have type std::function<...>.
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.
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;
}
I have a the following template and specialization (this code is not correct, but hopefully demonstrates my intent well enough):
template <typename T> widget &&make_widget(T &&val) { // (1)
return std::move(widget(std::forward<T>(val)));
}
template <> widget &&make_widget(void) { // (2)
return std::move(widget());
}
The intent is to have a factory function that can be called like this:
make_widget(arbitrary_function());
And have it choose the default constructor if arbitrary_function returns void.
However, with clang 3.7 I get the following error:
error: no function template matches function template specialization 'make_widget'
pointing to the line of (2). How can I implement this correctly?
You can't do this. It's impossible to create a function that has a parameter of type void. What you can do is make the function variadic, like make_unique.
template <typename... T>
widget make_widget(T&&... val) {
return widget(std::forward<T>(val)...);
}
Then if you want to do something like
auto w = make_widget(void_function());
there is nothing stopping you from just doing instead:
void_function();
auto w = make_widget();
or even, if you really need it to be one statement for some reason,
auto w = (void_function(), make_widget());
Three further notes:
You should nix the std::move in the return statement since the result of calling the constructor is already an rvalue.
Never return a reference (even rvalue reference) to a temporary! It will always become a dangling reference.
There is no point to the make_widget function if forwarding its arguments to the widget constructor is the only thing it does. Note that make_unique takes care of calling new for you, and that make_tuple deduces the template arguments for the tuple itself. Your make_widget function doesn't do anything like that.
As it's been pointed out, the problem is not really in the template specialization, but the usage of a void expression.
I can, however, suggest an alternative syntax that uses an intermediate lambda, and a helper template, to achieve the same results at a cost of a little bit of negligible extra usage syntax.
#include <functional>
class widget {
public:
widget();
widget(int);
};
template <typename T> widget &&do_make_widget(T &&val) { // (1)
return std::move(widget(std::forward<T>(val)));
}
widget &&do_make_widget() { // (2)
return std::move(widget());
}
template <typename T>
class do_make_widget_invoke {
public:
template<typename functor_type>
static auto invoke(functor_type &&functor)
{
return do_make_widget(functor());
}
};
template <>
class do_make_widget_invoke<void> {
public:
template<typename functor_type>
static auto invoke(functor_type &&functor)
{
functor();
return do_make_widget();
}
};
template<typename functor_type>
auto make_widget(functor_type &&functor)
{
return do_make_widget_invoke<decltype(functor())>
::invoke(std::forward<functor_type>(functor));
}
Testing the above with g++ 5.1.1 in -std=c++14 mode, I seem to get the right results with the following syntax, which is pretty much what you're trying to accomplish:
int foobar()
{
return 0;
}
int main()
{
make_widget([]{ return foobar(); });
}
and:
void foobar()
{
}
int main()
{
make_widget([]{ return foobar(); });
}
The return type of std::bind is (intentionally) unspecified. It is storable in a std::function.
The example program below shows how I have to explicitly cast the temporary object returned by std::bind() to a std::function in order to call fn1().
If the return type of std::bind was knowable, I could overload the Callback constructor & would no longer need to explicitly cast std::bind temporary objects.
Is there any way to avoid the explicit cast?
// g++ -std=c++11 test.cxx
#include <functional>
using std::placeholders::_1;
class A
{
public:
void funcA (int x) { }
};
class Callback
{
public:
Callback () = default;
Callback (std::function<void(int)> f) { }
// Wish we knew the return type of std::bind()
// Callback (return_type_of_std_bind f) { }
};
void fn0 (std::function<void(int)> f) { }
void fn1 (Callback cb) { }
int main (void)
{
A a;
fn0(std::bind(&A::funcA, &a, _1)); // ok
fn1(std::function<void(int)>(std::bind(&A::funcA, &a, _1))); // ok, but verbose
fn1(std::bind(&A::funcA, &a, _1)); // concise, but won't compile
}
Probably not relevant, but I'm using gcc 4.7.2 on Linux.
Best to give Callback a universal constructor:
struct Callback
{
typedef std::function<void(int)> ftype;
ftype fn_;
template <typename T,
typename = typename std::enable_if<std::is_constructible<ftype, T>::value>::type>
Callback(T && f) : fn_(std::forward<T>(f))
{ }
};
(I added the second, defaulted template argument to only enable this constructor for types T for which the statement makes sense, so as not to create false convertibility properties.) Note how this technique removes one implicit user-defined conversion from the conversion chain, by invoking an explicit constructor for fn_.