error: no > match for call to ‘(boost::_mfi::mf1<void - c++

I have rather a basic knowledge in c++ and there is an issue described in the following which is likely rather simple and a based on a syntax mistake but I haven't figured out a way around it.
Basically the error I get says:
remote_hw_interface_node.cpp:23:68: required from here
/usr/include/boost/function/function_template.hpp:231:11: error: no match for call to ‘(boost::_mfi::mf1<void, ROBOTHardwareInterface, const boost::shared_ptr<sensor_msgs::JointState_<std::allocator<void>
> > >&>) (const boost::shared_ptr<const sensor_msgs::JointState_<std::allocator<void> > >&)’
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
^
which I don't have any clue what it is about regarding boost.
regarding my code I have copied some parts of it in the following which may likely show the problem for a more experienced c++ user. My header file looks like:
#pragma once
#include <message_filters/subscriber.h>
#include <message_filters/time_sequencer.h>
// controller manager and interface msgs
#include <controller_manager/controller_manager.h>
class ROBOTHardwareInterface : public hardware_interface::RobotHW
{
public:
ROBOTHardwareInterface(ros::NodeHandle& nh);
~ROBOTHardwareInterface();
bool init (const urdf::Model* const urdf_model);
void sequential_update (const boost::shared_ptr <sensor_msgs::JointState> & joint_state_msg);
// main
ros::NodeHandle nh_;
ros::Duration elapsed_time_;
boost::shared_ptr<controller_manager::ControllerManager> controller_manager_;
};
the cpp file also if I only copy the relevant parts which has also caused the error coming up:
#include <remote_hw.h>
ROBOTHardwareInterface::ROBOTHardwareInterface(ros::NodeHandle& nh) : nh_(nh) {
message_filters::Subscriber <sensor_msgs::JointState> sub(nh_, "joint_cmd_topic", 1);
message_filters::TimeSequencer <sensor_msgs::JointState> seq(sub, ros::Duration(
0.1), ros::Duration(0.01), 10);
seq.registerCallback(&ROBOTHardwareInterface::sequential_update);
}
ROBOTHardwareInterface::~ROBOTHardwareInterface() {
}}
void ROBOTHardwareInterface::sequential_update(const boost::shared_ptr <sensor_msgs::JointState> & joint_state_msg){

By searching in boost library implementation https://www.boost.org/doc/libs/1_71_0/boost/function/function_template.hpp, it seems that you are trying to call a method without giving all the parameters necessary.
I suppose that you try to invoke this method with an empty parameter, while you should also add const boost::shared_ptr <sensor_msgs::JointState> & as well.
I suppose that BOOST_FUNCTION_ARGS in your case is empty hence your issue. So the method behind is trying to invoke void sequential_update() instead of void sequential_update(const boost::shared_ptr <sensor_msgs::JointState> &)
I hope this helps.

Related

TextureCache::addImageAsync selector typecast issue

I'm trying to use addImageAsync for the first time, but i cannot get the syntax working. I'm using Cocos2dx 3.3 final and Xcode 6.1.1.
My code is as follows :
(GFXManager.h)
#include "cocos2d.h"
class GFXManager
{
...
void loadStuff();
void textureLoaded(Ref* pObj);
}
(GFXManager.cpp)
...
void GFXManager::loadStuff()
{
std::string path = "whatever.png";
Director::getInstance()->getTextureCache()->addImageAsync(path, callfuncO_selector(GFXManager::textureLoaded));
}
void GFXManager::textureLoaded(Ref* pObj)
{
...
}
The above is based on the "Texture2dTest" sample from Cocos2dx.
But at the line with the addImageAsync instruction Xcode keeps saying this:
Static_cast from 'void (GFXManager::*)(cocos2d::Ref * )' to 'cocos2d::SEL_CallFuncO' (aka 'void (cocos2d::Ref::*)(cocos2d::Ref *)') is not allowed
I tried making 'GFXManager' a class derived from 'Layer' (as in Texture2dTest), and using 'CCObject' in place of 'Ref' (as in Texture2dTest...But 'CCObject' is deprecated and now it is called 'Ref'), with no luck.
But every example i've found on the web about using addImageAsync calls the selector with that syntax.
So what am i doing wrong ?
You need to change callfuncO_selector with std::bind or CC_CALLBACK_1:
void GFXManager::loadStuff()
{
std::string path = "whatever.png";
Director::getInstance()->getTextureCache()->addImageAsync(path, CC_CALLBACK_1(GFXManager::textureLoaded, this));
}
because TextureCache::addImageAsync accepts std::function not the function pointer

C++ - "Unspecialised class template" error with shared_ptr

I have a class Room and it holds a vector of shared_ptrs to Option objects like so:
private:
vector<shared_ptr<Option> > options;
But for some reason when I build, I get the following errors:
'shared_ptr' : unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
'std::tr1::shared_ptr' : use of class template requires template argument list
Strangely, I also have a vector of shared_ptrs, exact same syntax but there's no problem with that one.
There's also a bunch of places that bring up the error "'Option': undeclared identifier", which brings me to think it might be a problem with the Option class, but it seems to be fine. Here's the code for Option:
Option.h:
#pragma once
#include "Room.h"
#include <memory>
using namespace std;
class Option
{
protected:
int id;
char* text;
public:
Option(void);
Option(int, char*);
virtual ~Option(void);
char* getText();
int getID();
};
Option.cpp:
#include "Option.h"
#include "Room.h"
#include <memory>
using namespace std;
Option::Option(void)
{
}
Option::Option(int newID, char* newText){
id = newID;
text = newText;
}
Option::~Option(void)
{
}
char* Option::getText(){
return text;
}
int Option::getID(){
return id;
}
There is a bit of conjecture in this answer since you haven't posted the code for the Room class. I'm assuming this code
private:
vector<shared_ptr<Option> > options;
is in Room.h. Your Option.h file includes Room.h, hence the Room class gets declared before the Option class. So Option is an incomplete type when the Room class' destructor is compiled and the shared_ptr implementation tries to delete the Option object.
From the code above, I don't see why Option.h needs to include Room.h, in fact, it should be the other way around. If it does indeed need to include the file, you should be able to work around the problem by explicitly declaring Room::~Room() out-of-line in Room.cpp.
EDIT:
Turns out ~shared_ptr<T> does not require T to be a complete type. However, shared_ptr<T>( T* ) and shared_ptr<T>::reset( T* ) do, and the problem may be because some operation on the vector is invoking a call to one of these (more likely the former).
vector<shared_ptr<Option >>
You almost did that right :)
vector<shared_ptr<Option> >
It's the two > characters that, when touching, cause the strange errors you see. It is being interpreted as the >> operator.
BTW, thank you for posting your code exactly as it is rather than typing it back in and possibly hiding the mistake.

Higher-order functions in C++, using std::wcout fails with error C2248

I'm playing around with implementing functional-style stuff in C++. At the moment, I'm looking at a continuation-passing style for enumerating files.
I've got some code that looks like this:
namespace directory
{
void find_files(
std::wstring &path,
std::function<void (std::wstring)> process)
{
boost::filesystem::directory_iterator begin(path);
boost::filesystem::directory_iterator end;
std::for_each(begin, end, process);
}
}
Then I'm calling it like this:
directory::find_files(source_root, display_file_details(std::wcout));
...where display_file_details is defined like this:
std::function<void (std::wstring)>
display_file_details(std::wostream out)
{
return [&out] (std::wstring path) { out << path << std::endl; };
}
The plan is to pass a continuation to find_files, but to be able to pass composed functions into it.
But I get the error:
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' :
cannot access private member declared in
class 'std::basic_ios<_Elem,_Traits>'
What am I doing wrong? Am I insane for trying this?
Note: my functional terminology (higher-order, continuations, etc.) is probably wrong. Feel free to correct me.
In display_file_details, you need to take your wostream by reference. iostream copy constructors are private.
Upon looking more deeply into the compiler output, I found this:
This diagnostic occurred in the compiler generated function
'std::basic_ostream<_Elem,_Traits>::
basic_ostream(const std::basic_ostream<_Elem,_Traits> &)'
It turns out that basic_ostream doesn't have an available copy constructor.
Changing std::wostream out to std::wostream & out fixes it. At least to the point that I get a bunch of other errors. These were easily fixed by:
std::for_each(begin, end,
[&process] (boost::filesystem::directory_entry d)
{ process(d.path().wstring()); });

Using boost::iostreams::mapped_file_source with wide character strings

If I instantiate a mapped_file_source (boost 1.46.1 ) with a narrow character string as in the following I don't have a problem:
boost::iostreams::mapped_file_source m_file_( "testfile.txt" );
However if I try to use a wide string:
boost::iostreams::mapped_file_source m_file_( L"testfile.txt" );
I get the following compiler error in VC2010 SP1:
P:\libs\boost_1_46_1\boost/iostreams/device/mapped_file.hpp(128): error C2248: 'boost::iostreams::detail::path::path' : cannot access private member declared in class 'boost::iostreams::detail::path'
P:\libs\boost_1_46_1\boost/iostreams/detail/path.hpp(111) : see declaration of 'boost::iostreams::detail::path::path'>
P:\libs\boost_1_46_1\boost/iostreams/detail/path.hpp(37) : see declaration of 'boost::iostreams::detail::path'
If I instead try to pass the constructor a boost::filesystem::path I get the following error:
P:\libs\boost_1_46_1\boost/iostreams/device/mapped_file.hpp(128): error C2664: 'boost::iostreams::detail::path::path(const std::string &)' : cannot convert parameter 1 from 'const boost::filesystem3::path' to 'const std::string &'
Reason: cannot convert from 'const boost::filesystem3::path' to 'const std::string'
I feel like I'm missing something obvious, but I'm just running around in circles trying to figure out what the compiler is trying to tell me, but I'm just getting lost. That palm to forehead moment is just not happening.. What is it that I am doing incorrectly?
The constructor defined in mapped_file.hpp looks like the following:
// Constructor taking a parameters object
template<typename Path>
explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
The basic_mapped_file_params class constructors look like this:
// Construction from a Path
explicit basic_mapped_file_params(const Path& p) : path(p) { }
// Construction from a path of a different type
template<typename PathT>
explicit basic_mapped_file_params(const PathT& p) : path(p) { }
Where the template class is defined as:
// This template allows Boost.Filesystem paths to be specified when creating or
// reopening a memory mapped file, without creating a dependence on
// Boost.Filesystem. Possible values of Path include std::string,
// boost::filesystem::path, boost::filesystem::wpath,
// and boost::iostreams::detail::path (used to store either a std::string or a
// std::wstring).
template<typename Path>
struct basic_mapped_file_params
: detail::mapped_file_params_base
{
There is some additional help in the header that says:
// For wide paths, instantiate basic_mapped_file_params
// with boost::filesystem::wpath
If I take this approach with:
boost::iostreams::basic_mapped_file_params<boost::filesystem::wpath> _tmp(L"test.txt");
boost::iostreams::mapped_file_source m_file_( _tmp );
I get the same C2664 error mentioned above..
I know the compiler is telling me what the problem is, but looking at the header source and the comments leads me to believe that what I'm trying to accomplish is supported, it's just my approach that is incorrect. Am I misinterpreting what the header file is telling me? I know there is probably a good lesson about template instantiation and explicit/implicit conversion in here somewhere.
Interestingly enough, upgrading my boost install to 1.47.0 seems to cleared up C2664 error but I'm still getting the C2248 error about access to the private member.
With boost 1.48 I can do something like this.
#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>
int main()
{
boost::filesystem::path p(L"b.cpp");
boost::iostreams::mapped_file file(p); // or mapped_file_source
std::cout << file.data() << std::endl;
}
or you can do this with mapped_file_params(used create new file)
boost::filesystem::path p(L"aa");
basic_mapped_file_params<boost::filesystem::path> param; // template param
param.path = p;
param.new_file_size = 1024;
It's telling you that boost::iostreams::mapped_file_source's constructor does not take a wchar_t*, nor does it take a boost::filesystem::path. It only takes std::string, or types convertible to std::string. Or, to put it another way, you can't use UTF-16 paths with this object.
It looks like the documentation for mapped_file is pretty old and does not reflect what is in the header or in the header comments. In order to instantiate a boost::iostreams:mapped_file_source object with a wide character string you need to explicity pass in the boost::iostreams::detail::path like this:
boost::iostreams::mapped_file_source m_file_( boost::iostreams::detail::path(boost::filesystem::path(L"testfile.txt")) );
I was able to get this to compile by stepping thought the error messages and determining how the template classes were being instantiated and finally saw that boost::iostreams::detail::path had a private constructor that took a &std::wstring as a parameter which is where the code was failing to compile.

Calling a member function with member data by using for_each

Dear all, I would like to call a member function (that expects a reference) for each object of (let's say) a vector that is a member of the same class, as the following code shows:
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct Stuff {
double x;
};
class Test {
public:
void f1(Stuff & thing);
void f2(void);
vector<Stuff> things;
};
void Test::f1(Stuff & thing) {
; // do nothing
}
void Test::f2(void) {
for_each(things.begin(), things.end(), f1);
}
int main(void)
{
return 0;
}
This codes gives me a compiler error related to unresolved overloaded function type . I have tried also with bind, but it seems that the references requisite in f1 is one problem. I know I am missing something important here, so I take this opportunity to solve my problem and to learn. At the moment, I can't install boost, but I would like to know also if boost is useful to solve this problem. Thanks in advance.
The function you want to call cannot be simply identified by f1 but should be referred to as &Test::f1 (as in : member function f1 of class Test)
Function f1 does not take a single argument : as any non-static member function it has an implicit this parameter of type Test * const
Finally, a standard bind won't be able to do the trick because it doesn't handle parameters passed by reference.
Boost.Bind would indeed be a great option :
std::for_each(things.begin(), things.end(), boost::bind(&Test::f1, this, _1));