I am using the code from the example here Keep order details in arrays?
I am getting an error of listOfTrades - undeclared identifier when I add the code in the
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
delete(listOfTrades);
}
I have a feeling it is because listOfTrades is declared in the OnInit() and not outside global but not sure how that would affect it.
Main.mql
#include <CTrade.mqh>
int OnInit()
{
CArrayObj *listOfTrades=new CArrayObj;
}
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
delete(listOfTrades);
}
Yes, you have to declare that globally, before calling OnInit(). Missed that point in the mentioned question, will update.
If you pass the object by pointer somehow void OnTick(){ doSomeFunction(listOfTrades); } then you should make sure the same variable name is not used (at least in the same file), otherwise you will have warnings that some day may become a bug.
void doSomeFunction(CArrayObj* _listOfTrades)// not "listOfTrades" !!!
{
for(int i=_listOfTrades.Total()-1;i>=0;i--)
{
CTrade* trade=_listOfTrades.At(i);
// action with CTrade object
}
}
Related
Using C++ 17, I'm looking for a way to store a lambda that captures the this pointer, without using std::function<>. The reason to not using std::function<> is that I need the guaranty that no dynamic memory allocations are used. The purpose of this, is to be able to define some asynchronous program flow. Example:
class foo {
public:
void start() {
timer(1ms, [this](){
set_pin(1,2);
timer(1ms, [this](){
set_pin(2,1);
}
}
}
private:
template < class Timeout, class Callback >
void timer( Timeout to, Callback&& cb ) {
cb_ = cb;
// setup timer and call cb_ one timeout reached
...
}
??? cb_;
};
Edit: Maybe it's not really clear: std::function<void()> would do the job, but I need / like to have the guaranty, that no dynamic allocations happens as the project is in the embedded field. In practice std::function<void()> seems to not require dynamic memory allocation, if the lambda just captures this. I guess this is due to some small object optimizations, but I would like to not rely on that.
You can write your own function_lite to store the lambda, then you can use static_assert to check the size and alignment requirements are satisfied:
#include <cstddef>
#include <new>
#include <type_traits>
class function_lite {
static constexpr unsigned buffer_size = 16;
using trampoline_type = void (function_lite::*)() const;
trampoline_type trampoline;
trampoline_type cleanup;
alignas(std::max_align_t) char buffer[buffer_size];
template <typename T>
void trampoline_func() const {
auto const obj =
std::launder(static_cast<const T*>(static_cast<const void*>(buffer)));
(*obj)();
}
template <typename T>
void cleanup_func() const {
auto const obj =
std::launder(static_cast<const T*>(static_cast<const void*>(buffer)));
obj->~T();
}
public:
template <typename T>
function_lite(T t)
: trampoline(&function_lite::trampoline_func<T>),
cleanup(&function_lite::cleanup_func<T>) {
static_assert(sizeof(T) <= buffer_size);
static_assert(alignof(T) <= alignof(std::max_align_t));
new (static_cast<void*>(buffer)) T(t);
}
~function_lite() { (this->*cleanup)(); }
function_lite(function_lite const&) = delete;
function_lite& operator=(function_lite const&) = delete;
void operator()() const { (this->*trampoline)(); }
};
int main() {
int x = 0;
function_lite f([x] {});
}
Note: this is not copyable; to add copy or move semantics you will need to add new members like trampoline and cleanup which can properly copy the stored object.
There is no drop in replacement in the language or the standard library.
Every lambda is a unique type in the typesystem. Technically you may have a lambda as a member, but then its type is fixed. You may not assign other lambdas to it.
If you really want to have an owning function wrapper like std::function, you need to write your own. Actually you want a std::function with a big enough small-buffer-optimization buffer.
Another approach would be to omit the this capture and pass it to the function when doing the call. So you have a captureless lambda, which is convertible to a function pointer which you can easily store. I would take this route and adapter complexer ways if really nessessary.
it would look like this (i trimmed down the code a bit):
class foo
{
public:
void start()
{
timer(1, [](foo* instance)
{
instance->set_pin(1,2);
});
}
private:
template < class Timeout, class Callback >
void timer( Timeout to, Callback&& cb )
{
cb_ = cb;
cb_(this); // call the callback like this
}
void set_pin(int, int)
{
std::cout << "pin set\n";
}
void(*cb_)(foo*);
};
I have an interface wherein the types of the parameters mostly encode their own meanings. I have a function that takes one of these parameters. I'm trying to make a function that takes a set of these parameters and performs the function on each one in order.
#include <iostream>
#include <vector>
enum param_type{typeA,typeB};
template <param_type PT> struct Container{
int value;
Container(int v):value(v){}
};
int f(Container<typeA> param){
std::cout<<"Got typeA with value "<<param.value<<std::endl;
return param.value;
}
int f(Container<typeB> param){
std::cout<<"Got typeB with value "<<param.value<<std::endl;
return param.value;
}
My current solution uses a recursive variadic template to delegate the work.
void g(){}
template <typename T,typename...R>
void g(T param,R...rest){
f(param);
g(rest...);
}
I would like to use a packed parameter expansion, but I can't seem to get that to work without also using the return values. (In my particular case the functions are void.)
template <typename...T> // TODO: Use concepts once they exist.
void h(T... params){
// f(params);...
// f(params)...; // Fail to compile.
// {f(params)...};
std::vector<int> v={f(params)...}; // Works
}
Example usage
int main(){
auto a=Container<typeA>(5);
auto b=Container<typeB>(10);
g(a,b);
h(a,b);
return 0;
}
Is there an elegant syntax for this expansion in C++?
In C++17: use a fold expression with the comma operator.
template <typename... Args>
void g(Args... args)
{
((void)f(args), ...);
}
Before C++17: comma with 0 and then expand into the braced initializer list of an int array. The extra 0 is there to ensure that a zero-sized array is not created.
template <typename... Args>
void g(Args... args)
{
int arr[] {0, ((void)f(args), 0)...};
(void)arr; // suppress unused variable warning
}
In both cases, the function call expression is cast to void to avoid accidentally invoking a user-defined operator,.
You can write the prototypes without the variable names?
int example(examplestruct *var1, examplestruct *var2);
void done(examplestruct *var1,FILE *f);
struct {
int* field1;
int field2;
}examplestruct;
Is it possible to write the prototypes without name variables?
Can anyone tell me if this is acceptable in C language? You can write the prototypes without the variable names?
Yes.
As for the second question:
If you want a function to be inside main(), then take the body of the function, put it in main() and make sure that the arguments that the function had are well handled.
This example will clear things up:
#include <stdio.h>
void print(int);
void inc_p(int);
int main(void) {
int num = 5;
print(num);
inc_p(num);
// to get rid of inc_p(), copy paste it's body inside main
// and you will get this
// a++;
// print(a);
// However, a was an argument, here you need to use
// the variable declared in main(), i.e. 'num'
num++;
print(num);
return 0;
}
void print(int a) {
printf("%d\n", a);
}
void inc_p(int a) {
a++;
print(a);
}
The error while creating a button in opencv
argument of type 'void (Window::)(int, void*)' does not match 'cv::ButtonCallback {aka void ()(int, void)}'
class Window{
void ChecKBox(int state, void* val){
// do nothing for now
return;
}
public:
void createCheckbox(){
cv::createButton(checkboxname, CheckBox, NULL, CV_CHECKBOX, 0);
}
};
int main(){
Window w;
w.createCheckBox();
}
I can't seem to find the fix to this problem.
oh, you can't pass in a member function of a class here. think of it, where would the 'this' pointer come from ? (like you call class members like w.CheckBox(1,NULL); there is no 'w' here. )
the highgui interface is a bit limited. it can only call free functions or static members.
so, if your callback function does not need anything from Window, make it static:
class Window {
static void CheckBox(int state, void* val) { /*you can't use 'this' here!*/ return; }
public:
void createCheckBox() { cv::createButton(checkboxname, CheckBox, NULL, CV_CHECKBOX, 0); }
};
int main() {
Window w;
w.createCheckBox();
}
I am trying to create a thread using pthread. So far I have this:
sample.h:
void* ReceiveLoop(void*);
pthread_t mythread;
sample.cpp:
void* ReceiveLoop(void*) {
cout<<"whatever";
}
void sample::read() {
pthread_create(&mythread, NULL, ReceiveLoop, NULL);
}
Which I think is ok having read some posts about this. I have also tried with
pthread_create(&mythread, NULL, &ReceiveLoop, NULL);
But I get this:
.cpp:532: error: no matches converting function 'ReceiveLoop' to type 'void* (*)(void*)'
.cpp:234: error: void* sample::ReceiveLoop(void*)
Anyone can help me? Thanks.
I recall a few idiosyncrasies between older versions of gcc/g++ with regards to errors like this. You didn't indicate the compiler you were using.
Go ahead and give the void* parameter passed to ReceiveLoop a name:
void ReceiveLoop(void* threadarg);
void* ReceiveLoop(void* threadarg){ cout<<"whatever"; }
For some reason, I seem to recall that's the only way I could get a particular piece of code to compile on some random compiler even though the parameter passed in wasn't actually used.
Also, if ReceiveLoop is a member function of a class, it needs to be declared static.
class sample
{
public:
void ReceiveLoopImpl()
{
cout<<"whatever";
}
static void* ReceiveLoop(void* threadargs)
{
return ((sample*)threadargs)->RecieveLoopImpl();
}
void read()
{
pthread_create(&mythread, NULL, sample::ReceiveLoop, this);
}
};