I am trying to evaluate a part of my code asynchronously
#include <stdio.h>
#include <string>
#include <memory>
#include <future>
#include <map>
namespace IG
{
typedef std::map<uint, std::string> CadDef;
class FooFoo
{
CadDef foo()
{
CadDef cdef{};
cdef[1] = "aa";
return cdef;
}
};
}
int main()
{
auto ptr = std::make_unique<IG::FooFoo>();
std::future<IG::CadDef> resFut = std::async(ptr->foo);
auto res = resFut.get();
return 0;
}
But the code doesn't compile -
(On gcc)
error: invalid use of non-static member function ‘IG::CadDef IG::FooFoo::foo()’
(on msvc -- my main program, from where I abstracted the minimal example)
error C3867: 'IG::FooFoo::foo': non-standard syntax; use '&' to create a pointer to member
error C2672: 'std::async': no matching overloaded function found
error C2780: 'std::future<_Invoke_traits<void,decay<_Ty>::type,decay<_ArgTypes>::type...>::type> std::async(std::launch,_Fty &&,_ArgTypes &&...)': expects 3 arguments - 1 provided
Seems like MSVC is complaining that I have not used ptr->foo() but I am not sure.
What am I doing wrong?
You can use a lambda like following, using a policy*
auto handle = std::async(std::launch::async, [&ptr](){
return ptr->foo(); // Ofcourse make foo public in your snippet
});
auto res = handle.get();
*Not necessarily required
Async takes a function address as an argument, but it the function is a class-member function you have to bind it to the object which can invoke this function.
All functions (including methods) are moved to the code segment of the binary file.
That's why the sizeof(T) equals to sum of sizeof of all class data-members (including a virtual table pointer (vptr) if exists).
class A {void method() }; can be represented as void method(A* a) {}
Knowing all this information you should bind the method with the object
int main()
{
auto ptr = std::make_unique<IG::FooFoo>();
std::future<IG::CadDef> resFut = std::async(&IG::FooFoo::foo, ptr.get());
auto res = resFut.get();
return 0;
}
Related
I'm trying to use decltype, but I got the same error every time when I was trying compile.
#include <iostream>
#include <cmath>
using namespace std;
class Polygon {
private:
double bok;
int katy;
public:
Polygon(int katy,double bok): katy (katy),bok (bok) {};
void scale(double s){ bok*=s;};
double area () const{
return (katy*(bok*bok))/(4.0*tan((M_PI/katy)));}};
int main(){
Polygon polygon(7,10.);
polygon.scale(2.);
cout<<polygon.area()<<endl;
if(!std::is_same<decltype(scale),void (Polygon*,double)>::value){
cout<<'p';
}
}
I got a error: "
error: ‘scale’ was not declared in this scope; did you mean ‘scalb’?
28 | if(!std::is_same<decltype(scale),void (Polygon*,double)>::value){
"
What's wrong?
You need to take a pointer to the member function and prefix it with the class scope in order to refer to it:
if (!std::is_same<decltype(&Polygon::scale), void(Polygon*, double)>::value) {
cout<<'p';
}
Be advised, however, that member function type is not a plain function pointer, as for each class there is special type defined within the class scope, which follows this pattern: ReturnType(ClassName::*)(args). Thus in your scenario, if you expect std::is_same to match the function, you should specify the conditional expression as follows:
std::is_same_v<
decltype(&Polygon::scale),
void(Polygon::*)(double)
>
I am trying to implement an execution pattern which takes any function and executes it with its own conditions/preparations. Regardless of this being a useful thing to do, it just doesn't work. It seems i can't access the template overload of the "Execute"-function (called in "main").
Specifically: Why can't i call the overloaded template function of Execute?
This is the full program:
#include "stdafx.h"
#include <functional>
class TransparentFunctionWrapper
{
public:
virtual void Execute(std::function<void()> executeFunction) = 0;
template<class C>
C Execute(std::function<C(void)> executeFunction) // template-overload of the abstract function which will implicitly call it
{
C ret;
Execute( // calls the abstract function with a lambda function as parameter
[ret, executeFunction](void) -> C // lambda declaraction
{ //
ret = executeFunction; // lambda body
}); //
return ret;
}
};
class ExampleExecutor : public TransparentFunctionWrapper
{
public:
virtual void Execute(std::function<void()> executeFunction)
{
printf("executed before.");
executeFunction();
printf("executed after.");
}
};
void DoStuff() {}
int ReturnStuff() { return -5; }
int main()
{
ExampleExecutor executor;
executor.Execute(DoStuff);
int i = executor.Execute<int>(ReturnStuff); // Why does this not work? ERROR: "type name is not allowed"
getchar();
return 0;
}
Note: Visual Studio marks
Execute<int>(ReturnStuff) // "int" is marked as Error: type name is not allowed
The compilation puts out the error
"type 'int' unexpected"
Thanks to everyone willing to help!
ExampleExecutor::Execute is not overriding TransparentFunctionWrapper::Execute, and it is hiding it in the executor.Execute<int> call.
You must explicitly call TransparentFunctionWrapper::Execute, as it is hidden by ExampleExecutor::Execute. Here's a possible way of doing that:
int i = executor.TransparentFunctionWrapper::Execute<int>(ReturnStuff);
live example on coliru
I am facing an error in one of my projects which I have replicated using a standalone program. I did see several posts pertinent to this, but could not figure out my problem. I am getting the following error with this code : "error: expected constructor, destructor, or type conversion before '&' token"
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
class X
{
private:
int _x;
public:
X(int x) : _x(x) {};
};
class Y
{
private:
typedef boost::shared_ptr<X> X_ptr;
public:
X_ptr& func1();
};
X_ptr& Y::func1()
{
X_ptr p(new X(8));
return p;
};
int main()
{
return 0;
}
Can someon help me with in resolving this error?
There are two problems. First, you forgot to qualify the type name X_ptr:
Y::X_ptr& Y::func1()
// ^^^ ^
// BUT REMOVE THIS!
Second, notice that you are returning a reference to a local variable. Attempting to dereference the value returned by func1() will give you undefined behavior.
Just change the prototype of your function this way:
Y::X_ptr Y::func1()
// ^^^^^
// Returning the smart pointer by value now
{
X_ptr p(new X(8));
return p;
}
I have this problem with signal():
This code compiles fine:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void terminate( int param )
{
printf ( "Terminating program...\n" );
exit( 1 );
}
int main()
{
signal( SIGTERM, terminate );
return 0;
}
The following code, however, throws this error:
g++ -Wall -c -g goober.cpp
goober.cpp: In member function `void GOOBER::yarrgh()':
goober.cpp:5: error: argument of type `void (GOOBER::)(int)' does not match `
void (*)(int)'
make: *** [goober.o] Error 1
goober.h:
#ifndef GOOBER_H
#define GOOBER_H
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
using namespace std;
class GOOBER {
public:
GOOBER(){}
~GOOBER(){}
void yarrgh();
void terminate( int param );
};
#endif
goober.cpp:
#include "goober.h"
void GOOBER::yarrgh()
{
signal( SIGTERM, terminate );
}
void GOOBER::terminate( int param )
{
printf( "Terminating program...\n" );
exit( 1 );
}
driver.cpp:
#include "goober.h"
using namespace std;
int main()
{
GOOBER G;
G.yarrgh();
return 0;
}
I don't see any difference in the code, other than I'm calling signal() in a member. Any ideas what's wrong, and how to fix it?
You need to declare your terminate() function as static:
class GOOBER {
// ...
static void terminate(int param);
};
This is because that as a non-static member function, the terminate() function expects to be passed the (hidden) this parameter to point to some instance of the object. Since the signal mechanism doesn't know about this (or about anything much of C++), you need to use a static function so that there is no hidden this parameter.
I can tell you what's wrong:
You cannot use a non-static member function like a normal function pointer. Member functions always have an implicit this argument, which is provided (implicitly) by the caller. A C API cannot do this.
Terminate has to be a static function in the class.
Member function have different signature from normal function that not belong any class. However, static member function have the same signature with normal function. So, you could declare your terminate member function in GOOBER class as static.
Take the following C/C++ code:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*foo(bool))(int); // foo is &(bool→(int→int))
foo = baz;
}
Attempting to compile this (gcc or g++) gives:
$ g++ test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: assignment of function ‘int (* foo(bool))(int)’
test.cc:9: error: cannot convert ‘int (*(bool))(int)’ to ‘int (*(bool))(int)’ in assignment
Check for yourself: the two types it claims it cannot convert between are exactly the same. Why then is it claiming that they are incompatible?
EDIT 1: The problem disappears when using typedefs (as is recommended), like so:
int main() {
typedef int (*int2int)(int);
typedef int2int (*bool2_int2int)(bool);
bool2_int2int foo;
foo = baz;
}
EDIT 2: The compiler, of course, was right. The problem with my original code, as many pointed out, is that foo in main() is a declaration of a function, and not a function pointer. The error in the assignment was therefore not conflicting types but assigning to a function, which is not possible. The correct code is:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool→(int→int))
foo = &baz;
}
The code is in fact wrong. The problem is that this line:
int (*foo(bool))(int); // foo is &(bool→(int→int))
... doesn't mean what you think it means. It's interpreted as a declaration of a function named "foo". That makes perfect sense. Think about it - if you had wanted to forward declare "baz", you would have put int (*baz(bool))(int); , right? Also, since baz is a function which returns a function pointer, and foo is a pointer to a function which returns a function pointer, wouldn't you expect the syntax to be more complicated?
You declared foo as a function of the same type as baz, rather than as a pointer to a function of same type as baz.
From your compiler, the first error message is the useful one - it tells you assignment of function, i.e. you have tried to assign to a function, which is an error.
I'm not even going to try to write the correct solution without typedefs :-) Here's some code which compiles and I think is right, using typedefs:
#include <stdlib.h>
#include <stdbool.h>
typedef int(*IntReturnsInt)(int);
int inc(int i) { return i+1; }
IntReturnsInt baz(bool b) { return b ? &abs : &inc; }
int main() {
IntReturnsInt (*foo)(bool b);
foo = baz;
}
In this example the double-function-pointer concept is a bit clearer - IntReturnsInt is a function pointer type and foo is a pointer to a function which returns IntReturnsInt... phew :-)
This is a function declaration.
int (*foo(bool))(int);
If you wanted to declare a function pointer, you should do:
int (*(*foo)(bool))(int);
It's difficult to be sure, but I think this is closer to the OP's intent:
// baz is a function returning a pointer to a function
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
// foo is a pointer to a function
int (*foo)(int) ;
foo = baz(true); // Now foo is equal to &abs
}
you cannot assign to function type (int (*foo(bool))(int);), you need to use pointer to function
int (*(*foo)(bool))(int);
foo = &baz;
#include <stdlib.h>
#include <stdbool.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool→(int→int))
foo = baz;
return 0;
}
So there were a few side-issues clouding the core issue. Your "bool" was being interpreted as a default-int untyped parameter because the actual built-in is _Bool, humanized by the previously-missing #include <stdbool.h>. The lack of a pointer declaration for the object on the stack was confounding its ability to conform to the type of the real function object in static memory just above.
Once I included <stdbool.h>, the error shifted to "lvalue required" complaint, because there was only a function declaration and not a pointer object. The code above will compile with no warnings or errors.