Im trying to use my member function as a boost function , but it does not work.
I guess the following error message :
warning C4180: qualifier applied to function type has no meaning; ignored
...\boost\boost_1_55_0\boost\bind\bind_template.hpp(344) : see reference to class template instantiation 'boost::_mfi::dm<double (const std::vector<double,std::allocator<_Ty>> &),MyClass>' being compiled ...
then I have a popup message saying that I must click ok
and this message :
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(341,5): error MSB6006: "CL.exe" exited with code 1.
This is my code :
void MyClass::runProcess(){
boost::function<double(const std::vector<double> &)> f =
boost::bind(&MyClass::MyMemberFunction, this);
}
double MyClass::MyMemberFunction(const std::vector<double> & inX){
return 1.0;
}
You have to add a placeholder to bind() call:
#include <boost/bind/placeholders.hpp>
boost::function<double(const std::vector<double> &)> f =
boost::bind(&MyClass::MyMemberFunction, this, _1);
// ^^^
Related
I am trying to create a function func that returns an std::tuple of an std::unique_ptr<A> and a double. However, when I try to create the tuple I receive errors. The code follows:
#include <tuple>
#include <memory>
class A {
public:
A() : data (3){}
private:
double data;
};
std::tuple<std::unique_ptr<A>, double> func(double num) {
std::unique_ptr<A> a = std::make_unique<A>();
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(a, num); // ERROR MESSAGE C
return temp;
}
int main() {
return 0;
}
This code produces the following 4 errors in Visual Studio.
Error message A:
tuple(827,18): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to '_Ttype'
Error message B:
tuple(825,83): message : No constructor could take the source type, or constructor overload resolution was ambiguous
Error message C:
Source.cpp(14): message : see reference to function template instantiation 'std::tuple<std::unique_ptr<A,std::default_delete<A>>,double> std::make_tuple<std::unique_ptr<A,std::default_delete<A>>&,double&>(std::unique_ptr<A,std::default_delete<A>> &,double &)' being compiled
Error message D:
tuple(827,12): error C2064: term does not evaluate to a function taking 2 arguments
First, what is the cause of this error? Second, is the A associated with a being placed on the heap?
A std::unique_ptr is not copyable. You are attempting to copy a std::unique_ptr to the tuple, and that will not work. The compiler error message is kind of cryptic, IMO, but that is basically what seems to be the problem.
However, a std::unique_ptr is moveable, thus you can use std::move:
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(std::move(a), num);
This question already has answers here:
Passing arguments to std::async by reference fails
(3 answers)
Closed 2 years ago.
I have this code.
int TA11::AsyncRunP(Unit *unit,Function func)
{
return 0;
}
int TA11::AsyncRunR(Unit& unit, Function func)
{
return 0;
}
void TA11::RunFunc(Unit& unit, Function func)
{
assert(!unit.fut_.valid());
unit.fut_ = std::async(std::launch::async, &TA11::AsyncRunR, this, unit, func);
unit.fut_ = std::async(std::launch::async, &TA11::AsyncRunP, this, &unit, func);
}
VS2019 c++17 mode. (Function is a class enum)
the first std::async wont compile, second one is fine.
1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,19): error C2672:
'std::async': no matching overloaded function found
1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): error C2893:
Failed to specialize function template
'std::future<_Invoke_traits<void,decay<_Ty>::type,decay<_ArgTypes>::type...>::type> std::async(std::launch,_Fty &&,_ArgTypes &&...)' 1>C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\future(1481):
message : see declaration of 'std::async'
1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message : With the
following template arguments:
1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message :
'_Fty=int (__thiscall TA11::* )(TA11::Unit &,TA11::Function)'
1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message :
'_ArgTypes={TA11 *, TA11::Unit &, TA11::Function &}'
std::async passes the arguments to the callable by value (doesn't make perfect forwarding), hence you got the error because your callable only accepts reference.
You can use std::ref() to pass your var by reference.
I was looking at an answer to another question. However I can't figure out, based on that example, why can't I bind a value of some local variable with MSVC 2015 compiler? It just throws an error while gcc 5.3 compiles it fine on msys2/mingw64. I mean like in
#include <iostream>
#include <functional>
#include <vector>
int add(int a, int b) { return a + b; }
using bound_add_t = decltype(std::bind(add, std::placeholders::_1, int()));
int main() {
std::vector<bound_add_t> vec;
int y = 2;
vec.emplace_back(add,std::placeholders::_1, y); // <- this causes the problem
vec.emplace_back(add,std::placeholders::_1, 2);
vec.emplace_back(add,std::placeholders::_1, 3);
for (auto &b : vec)
std::cout << b(5) << std::endl;
return 0;
}
Severity Code Description Project File Line Suppression State
Error C2664 'std::_Binder &,int>::_Binder(std::_Binder &,int> &&)': cannot convert argument 3 from 'int' to 'int &&' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0 655
Is it a known issue tracked somewhere? I'm not even sure what is the underlying problem here. Is there a workaround?
In my use case, I'm missing one argument that becomes available later, so I'd want to have a vector with a wrapped function ready just like in that example.
Update
Is it a C++14 thing? I was poking around on http://ideone.com/Zi1Yht . While there is no MSVC, only compiler marked as C++14 was able to compile it.
Update 2
I tried
std::vector<std::function<int(int)> > vec;
vec.emplace_back(add, std::placeholders::_1, y);
if that was implied, I get
Severity Code Description Project File Line Suppression State
Error C2664 'std::function::function(std::function &&)': cannot convert argument 1 from 'int (__cdecl &)(int,int)' to 'std::allocator_arg_t' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0 655
MSVC is in its right in rejecting this code. int() is a temporary and therefore corresponding Args&&... parameter is deduced as int&&. So the constructor of the result type of bind can take int&& as the last parameter, and y is not an rvalue so compilation fails.
This is not a bug in other compilers, because the result of bind is unspecified.
If you don't want to fall back to std::function you can enforce the type of the last parameter to be const int&:
using bound_add_t = decltype(std::bind(add, std::placeholders::_1, std::declval<const int&>()));
The return type of std::bind is unspecified.
The required constructor is the copy constructor or the move constructor.
Construct it from the arguments (function, placeholders, ...) you give is unspecified and may work for specific implementation but is not portable.
As a workaround, you may do
std::vector<std::function<int(int)> > vec;
int y = 2;
vec.push_back(std::bind(add, std::placeholders::_1, y));
vec.push_back(std::bind(add, std::placeholders::_1, 2));
vec.push_back(std::bind(add, std::placeholders::_1, 3));
I found out that a std::packaged_task couldn't be pushed into a std::vector if the parameter type returns void in Visual Studio (2012, 2013, Nov 2013 CTP). For example,
typedef std::packaged_task<void()> packaged_task;
std::vector<packaged_task> tasks;
packaged_task package;
tasks.push_back(std::move(package));
The error messages are:
error C2182: '_Get_value' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2512: 'std::_Promise<int>' : no appropriate default constructor available
error C2665: 'std::forward' : none of the 2 overloads could convert all the argument types
I think this is bug because this code snippet works if
the return type is not void,
it is compiled in XCode.
Are there solutions or other options in Visual Studio? I know that boost can be used to replace this.
I can reproduce this with a simple auto m = std::move(package);.
int main()
{
typedef std::packaged_task<void()> packagedtask;
packagedtask p1;
packagedtask p2;
p2 = std::move(p1); // does not cause the error
auto p3 = std::move(p2); // causes the error
}
Trawling through the code, packaged_task has embedded typedefs as follows;
typedef typename _P_arg_type<_Ret>::type _Ptype;
typedef _Promise<_Ptype> _MyPromiseType;
_P_arg_type offers a non-void type when the return type is void. The packaged_task move constructor contains a reference to the internal _Promise as _Promise<_Ret>;
_MyPromise(_STD forward<_Promise<_Ret> >(_Other._MyPromise))
This then becomes _Promise<void> which in turn generates further invalid code that generates the list of errors seen. It should probably be;
_MyPromise(_STD forward<_MyPromiseType >(_Other._MyPromise))
// possibly even using a move
As the move assignment operator does.
As a workaround, consider adding a "dummy" or "unusable" return type of some sort;
struct unusable {};
Or just simply an int or boost as you have already suggested.
Consider this code snippet:
void Foo(std::string str1, std::string str2) {}
template<typename... Types>
void Bar()
{
Foo(Types{}...); // wont compile
}
Bar<std::string, std::string>();
What I want to do here is to default construct two std::string objects inside the Bar method and pass them to Foo. However my vain attempts (one of them being in the snippet) wont compile so I am wondering whether this is even possible.
I compiled with VC 2013, which throws compiler errors at me. As stated in the comments, other compilers can handle it. Can anyone tell whether the above snippet is standard conform?
It's a problem in the MSVC variadic template expansion process; when it unpacks the list of types it fails to recognise them as suitable for a constructor call. As a workaround, you can perform a type transformation to force the compiler to recognise them:
template<typename T> using identity_t = T; // NEW CODE
void Foo(int, int);
template<typename... Types>
void Bar()
{
Foo(identity_t<Types>{}...); // use identity type transformation
}
int main() {
Bar<int, int>();
}
I haven't managed to find an issue number yet.
This crashes the VC 2013 compiler for me. The errors seem to indicate that it has some problems parsing the code. So when the compiler crashes it must be a compiler bug.
1>main.cpp(23): error C2144: syntax error : 'std::string' should be preceded by ')'
1> main.cpp(28) : see reference to function template instantiation 'void Bar<std::string,std::string>(void)' being compiled
1>main.cpp(23): error C2660: 'Foo' : function does not take 0 arguments
1>main.cpp(23): error C2143: syntax error : missing ';' before '{'
1>main.cpp(23): error C2143: syntax error : missing ';' before ','
1>c1xx : fatal error C1063: INTERNAL COMPILER ERROR
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>cl : Command line warning D9028: minimal rebuild failure, reverting to normal build
1>
1>Build FAILED.