I have a simple task class:
template<typename TType>
class YHMTask
{
public:
YHMTask() {};
template<typename TLambdaFun>
auto then(TLambdaFun f) -> std::future<decltype(f(mTask.get()))>
{
std::move(mTask);
return std::async(std::launch::async, f, mTask.get());
}
std::future<TType> mTask;
private:
};
In this code, .then can be used and return a std::future.
But I want .then to return another YHMTask so that I can call .then after .then.
I tried to change .then code to follow:
template<typename TLambdaFun>
auto then(TLambdaFun f) -> YHMTask<decltype(f())>
{
std::move(mTask);
std::async(std::launch::async, f, mTask.get());
YHMTask<decltype(f())> yhmTask(std::move(this));
return yhmTask;
}
And call .then like this:
auto testTask = YHMCreateTask(PostAsync(L"", L"")).then([=](wstring str)
{
return 1;
});
Compilier give me this error:
error C2672: 'YHMTask<std::wstring>::then': no matching overloaded function found
error C2893: Failed to specialize function template 'YHMTask<unknown-type> YHMTask<std::wstring>::then(TLambdaFun)'
How should I do?
When you create yhmTask you are moving this, which is a pointer. There is no constructor for YHMTask that takes a pointer to a YHMTask so the template specialization fails. You should dereference this before moving it:
YHMTask<decltype(f())> yhmTask(std::move(*this));
Sounds like you are interested in extending std::future to have .then(). I recommend taking a look at Futures for C++ at Facebook. It does what your attempting to do and more.
Lets you chain a sequence tasks using then:
Future<double> fut =
fooFuture(input)
.then(futureA)
.then(futureB)
.then(futureC)
.then(d)
.then([](OutputD outputD) { // lambdas are ok too
return outputD * M_PI;
});
Also provides other compositional building blocks such as collect, map, and reduce. Git repo here. Looks like C++17 may also have support for the .then construct.
Related
I want to modify a templated google benchmark (with custom arguments) to run with a test fixture class, but don't know if this is really possible and if so, how the correct syntax is.
Just adding the fixture class doesn't seem to be enough.
static void CustomArguments(benchmark::internal::Benchmark* b) {
// define I, J
for (auto i : I)
{
for (auto j : J)
b->Args({i, j});
}
}
template<typename my_type>
class My_Fixture : public benchmark::Fixture
{
protected:
void SetUp(const ::benchmark::State& state) { ...}
virtual void TearDown() { ...}
};
template <typename any_type>
static void insert(benchmark::State& state)
{
for (auto _ : state)
{ ...}
}
BENCHMARK_TEMPLATE_F(My_Fixture, insert, my_type)->Apply(CustomArguments);
BENCHMARK_MAIN();
The compiler complains about the before-last code line
error: expected initializer before '->' token, but also fails to find the variable declarations from the fixture inside the test. This might be a consequence or an additional error. Do I need to register the fixture additionally? The example is running perfectly without fixture.
You'll need to use a slightly less convenient registration macro:
BENCHMARK_TEMPLATE_DEFINE_F defines the templated benchmark with the fixture. Then BENCHMARK_REGISTER_F can be used to register the benchmark, and that is where you'd add the ->Apply(CustomArguments) call.
See here for an example.
Is there any possible way to access the socket handle inside a boost asio async completion handler ? i looked at the boost asio placeholders but there is no variable which stores the socket handle.
You can just arrange for it, anyway you would outside boost or asio.
To bind a function that takes e.g. a socket to expose a void() function you can use bind:
int foo(std::string const& s, int);
std::function<void()> adapted = std::bind(foo, "hello world", 42);
So, usually you'd have code similar to this:
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this, boost::asio::placeholders::error));
Note, by using bind and this, we've bound a member function to the completion handler:
struct client
{
// ....
void handle_connect(boost::system::error_code err)
{
// you can just use `this->socket_` here
// ...
}
};
This implies that in handle_connect we can just use the socket_ member variable.
However, if you want to make things complicated you can use free functions as well
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&free_handle_connect, boost::ref(socket_), boost::asio::placeholders::error));
Now the implied handler function looks like
static void free_handle_connect(
boost::asio::ip::tcp::socket& socket_,
boost::system::error_code err)
{
// using `socket_` as it was passed in
int fd = _socket.native_handle_type();
}
Sorry about the title, I couldn't come with a better one.
Suppose that I have a class with special delete semantics, which needs to call a function instead of been deleted by delete, let's call it releaseable_object:
struct releaseable_object
{
releaseable_object() : dummy_ptr(new int) {}
void Release()
{
std::cout << "Releasing releaseable object\n";
delete dummy_ptr;
}
int *const dummy_ptr;
};
And this releaseable_object is the base class of a bunch of other objects, each of them constructed by a factory which only returns pointers.
I'm trying to wrap each class into a std::unique_ptr with a custom deleter which call the releaseable_object::Release() function, so I've created a helper struct to handle some of the generic stuff:
// std::is_base_of<releaseable_object, T>::value must be true
template <typename T> struct Managed
{
using type = T;
static void deleter(type *object)
{
std::cout << "Release!\n";
object->Release();
};
using pointer = std::unique_ptr<T, decltype(deleter)>;
};
And then, a bunch of derived classes which does all the specific initializations and calls to te factory:
struct ManagedA : Managed<A>
{
using base = Managed<A>;
using base::pointer;
using base::deleter;
ManagedA(/* lots of parameters */) :
m_pointer(nullptr, deleter)
{
// do A specific stuff...
A *a = factory::CreateA(/* lots of parameters */);
// more A specific stuff...
// wrap the pointer:
m_pointer.reset(a);
}
pointer m_pointer;
};
If I try to compile the code above, it complains about the unique_ptr (demo here), I don't know what I'm doing wrong there, the error is about the instantiation of a tuple (the complete error log is in the ideone demo):
tuple: In instantiation of ‘struct std::_Head_base<1u, void(A*), false>’:
tuple:229:12: recursively required from ‘struct std::_Tuple_impl<1u, void(A*)>’
tuple:229:12: required from ‘struct std::_Tuple_impl<0u, A*, void(A*)>’
tuple:521:11: required from ‘class std::tuple<A*, void(A*)>’
bits/unique_ptr.h:127:57: required from ‘class std::unique_ptr<A, void(A*)>’
If I get rid of the m_pointer member then the compilation succeeds. I'm pretty lost with this, I'll be grateful of any hints about how to fix the compilation error.
Thanks for your attention.
The problem is that decltype(deleter) is a function type instead of a pointer-to-function type. Changing the pointer declaration to
using pointer = std::unique_ptr<T, decltype(deleter)*>; // or spell out void(*)(T*)
will fix it.
Be aware that a function object type is usually preferable to a function pointer type for a unique pointer deleter, since the function pointer must be stored in the object itself. i.e.,
sizeof(std::unique_ptr<foo*,void(*)(foo*)>) == sizeof(foo*) + sizeof(void(*)(foo*))
but most implementations will take advantage of the Empty Base Optimization if you use an empty deleter type:
struct deleter_type {
void operator () (foo*) {
// ...
}
};
sizeof(std::unique_ptr<foo*,deleter_type>) == sizeof(foo*)
Here's how your sample code would be written using a deleter type..
i am new using c++11 features and also tryng to use SDL_Widget-2 lib for build a simple Gui for my project. But i am getting stuck in the problem :
#include "sdl-widgets.h"
class Builder
{
public:
Builder():top_win(nullptr)
,but(nullptr)
{
top_win=new TopWin("Hello",Rect(100,100,120,100),0,0,false,
[]() {
top_win->clear();
draw_title_ttf->draw_string(top_win->render,"Hello world!",Point(20,40));
}
);
but=new Button(top_win,0,Rect(5,10,60,0),"catch me",
[](Button *b) {
static int dy=60;
b->hide();
b->move(0,dy);
b->hidden=false;
dy= dy==60 ? -60 : 60;
});
}
private:
TopWin * top_win;
Button *but;
};
int main(int,char**) {
Builder aViewBuilder;
get_events();
return 0;
}
with the error in the compilation stage:
In lambda function:
error: 'this' was not captured for this lambda function
error: 'this' was not captured for this lambda function
this error is printed out twice int the console.
I have try :
[this](){}
[=](){}
and
[&](){}
with different compile error but a cannot go more further.
Can any see a fix?
You do need to capture with [this] or [&]. I suspect that the TopWin and Button constructors take raw function pointers, and need to take std::functions instead.
A plain vanilla function pointer is not compatible with capturing lambdas. std::function is able to work like a function pointer that also allows safe storage of captured data. (i.e. the captured objects will need to be properly copied or destroyed when the function object is itself copied or destroyed)
In N3257 I found an example using initializing members without a constructor, which is fine. I guess that is possible, because it is a POD.
template<typename T>
struct adaptor {
NonStdContainer<T>* ptr; // <- data member
T* begin() { return ptr->getFirst(); }
T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
for (auto i : adaptor<int>{&c}) // <- init
{ /* ... */ }
}
When I played around with this example I replaced the * with a &, because I don't like raw pointers:
template<typename T>
struct adaptor {
NonStdContainer<T>& ptr; // <- data member, now REF
T* begin() { return ptr->getFirst(); }
T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
for (auto i : adaptor<int>{c}) // <- init
{ /* ... */ }
}
This was fine and compiled without warning with GCC-4.7.0.
Then I got curious about the initialization of PODs and what might have changed with C++0x.
There I found Bjarnes FAQ. He says there that PODs may contain pointers, but no references.
Ops, now I wonder:
Do I have non-POD-object here, which the compiler can initialize without a constructor anyway and I just miss which mechanisms are used here?
or Is the GCC-4.7.0 behaving non-std by letting me initializing the ref this way?
or has there been a change in the std since Bjarnes FAQ that also allows references in PODs?
Update: I found aggregates in the current std (8.5.1 Aggregates [dcl.init.aggr]), but references are not mentioned there, so I am not sure how they relate to this
Quoting the standard [dcl.init.aggr]:
An aggregate is an array or a class (Clause 9) with no user-provided
constructors (12.1), no brace-or-equal- initializers for non-static
data members (9.2), no private or protected non-static data members
(Clause 11), no base classes (Clause 10), and no virtual functions
(10.3).
When an aggregate is initialized by an initializer list, as specified
in 8.5.4, the elements of the initializer list are taken as
initializers for the members of the aggregate, in increasing subscript
or member order. Each member is copy-initialized from the corresponding initializer-clause...
That means you have an aggregate here, aggregates can be initialized how you do it. PODs have nothing to do with it, they are really meant for communication with eg. C.
Copy-initialization of a reference with a variable is certainly legal, because that just means
T& ref = c;
Do I have non-POD-object here, which the compiler can initialize without a constructor anyway and I just miss which mechanisms are used here?
Yes, the object is non-POD.
Is the GCC-4.7.0 behaving non-std by letting me initializing the ref this way?
No.