Simple boost smart pointer syntax issue - c++

When using either boost::scoped_ptr or boost::shared_ptr I get the error
1>*\algomanager.cpp(28) : error C2064: term does not evaluate to a
function taking 1 arguments
I have code like this . . .
class X{
boost::shared_ptr<cPreFilterProcess> preProcess;
public:
X(){
preProcess(new cPreFilterProcess(pars));
}
};
What am I missing? Thanks.

My mythical glass orb of magic debugging tells me you're doing something like this:
class X{
boost::shared_ptr<cPreFilterProcess> preProcess;
public:
X(){
preProcess(new cPreFilterProcess(pars));
}
};
You need to use either the member initializer like:
X() : preProcess(...){}
Or use .reset since your can't just assign a pointer like that:
X() { preProcess.reset(...); }
I would strongly recommend the first option though.

If you just write this as a statement:
preProcess ( new cPreFilterProcess(pars) );
it's not valid, because preProcess is already constructed, so that syntax tries to "call" it like a function.
This is not valid either:
preProcess = new cPreFilterProcess(pars);
because you can't assign a cPreFilterProcess* to a shared_ptr<cPreFilterProcess>
Maybe you mean:
preProcess.reset( new cPreFilterProcess(pars) );
or
preProcess = boost::shared_ptr<cPreFilterProcess>( new cPreFilterProcess(pars) );

Related

How to pass a std::function or a function pointer into qtconnect?

This is mainly to clean up a bunch of code from my constructor. I have around 20+ lines of connect(object, func1, this, func2) in the constructor alone and I am trying to clean up the code by having a std::vector<std::tuple<QObject*,std::function<void()>,std::function<void>>>> connections;
It would work out quite nicely if I could do something like:
std::vector<std::tuple<QObject*,std::function<void()>,std::function<void>>>> connections = {
std::make_tuple(mySlider, std::bind(&QSlider::sliderReleased,mySlider, std::bind(&Foo::onSliderChanged,this)),
.
.
.
};
And then call it like this:
for(auto &&e : connections)
connect(std::get<0>(e),std::get<1>(e),this,std::get<2>(e));
However, when I do this I get an error that there is a substitution failure and a std::function<void()> cannot be converted into a function pointer. So decide to change it up and create actual function pointers like the following:
typename void(Foo::*fooFunc)();
typename void(QSlider::*sliderFunc)();
std::vector<std::tuple<QObject*,sliderFunc,fooFunc>> sliderConnections = {
std::make_tuple(mySlider, &QSlider::sliderReleased, &Foo::onSliderChanged),
.
.
.
};
And same thing, I then try to call it:
for(auto &&e : sliderConnections)
connect(std::get<0>(e),std::get<1>(e),this,std::get<2>(e));
However this also provides a similar error where there are no conversions. Which doesn't make any sense because now I am actually using a function pointer. Which according to the connection documentation it should be able to take a function pointer to connect them. So either I am passing it in incorrectly. Or what I am trying to achieve is not possible.
Any help would be appreciated!
After looking at G.M's comment I realized they were correct. A QObject* is not a QSlider* and therefore when trying to call the function QSlider::sliderReleased it couldn't connect the two because QObject does not have a slider. So once I changed that in the vector of tuples the code compiled just fine.
ex:
typedef void(Foo::*fooFunc)();
typedef void(QSlider::*sliderFunc)();
typedef void(QSpinBox::*spinFunc)();
const std::vector<std::tuple<QSlider*, sliderFunc, fooFunc>> sliderConnections = {
std::make_tuple(slider1, &QSlider::sliderReleased, &Foo::onSlider1Changed),
std::make_tuple(slider2, &QSlider::sliderReleased, &Foo::onSlider2Changed),
std::make_tuple(slider3, &QSlider::sliderReleased, &Foo::onSlider3Changed)
};
const std::vector<std::tuple<QSpinBox*, spinFunc, fooFunc>> spinConnections = {
std::make_tuple(spin1, &QSpinBox::editingFinished, &Foo::onSpin1Changed),
std::make_tuple(spin2, &QSpinBox::editingFinished, &Foo::onSpin2Changed),
std::make_tuple(spin3, &QSpinBox::editingFinished, &Foo::onSpin3Changed)
};
These will be private members in whatever class you are in charge of. And then in the constructor, instead of having 6 lines of connect(object,SIGNAL,object,SLOT), you can then put them into a function and call them like:
for(auto && tup : sliderConnections)
connect(std::get<0>(tup),std::get<1>(tup),this,std::get<2>(tup));
This successfully connects all the objects to their appropriate functions. Again, it's personal preference. I was just wondering if there was a way and G.M pointed me in the correct direction.

How to get a member function pointer in MSVC?

I'm not going to get into too much of the details on the Excel side of things, I essentially took code from this example:
C++ app automates Excel (CppAutomateExcel)
solution1.cpp
So I've tried this code in MSVC and it compiles:
class foo { public: virtual void bar(){} };
int main()
{
void (foo::*p)() = &foo::bar;
}
But similar code to capture the address of the move function in Excel does not work:
int main()
{
Excel::_ApplicationPtr spXlApp;
HRESULT hr = spXlApp.CreateInstance(__uuidof(Excel::Application));
Excel::WorkbooksPtr spXlBooks = spXlApp->Workbooks;
Excel::_WorkbookPtr spXlBook = spXlBooks->Add();
Excel::_WorksheetPtr spXlSheet = spXlBook->ActiveSheet;
HRESULT(Excel::_Worksheet::*pMove)(...) = &spXlSheet->Excel::_Worksheet::Move;
<... irrelevant code ...>
return 0;
}
This has the following compiler error:
error C2276: '&': illegal operation on bound member function expression
If I remove the &, it says I should add it back:
error C3867: 'Excel::_Worksheet::Move': non-standard syntax; use '&' to create a pointer to member
Any help on what to do here would be greatly appreciated.
You say in your question "but similar code..." and then you show code in which you do not do the same thing. Try using the same syntax for setting pMove as you used for setting p in your smaller example. Try something like &Excel::_Worksheet::Move; (without the "spXlSheet->").
If you can specify the specific instance of the object for which to call the function pointer at the time that you set the function pointer as you have there, I'm not aware of such a capability. After dropping spXlSheet-> from where you set the variable, use it instead where you want to call the function pointer.
You need to declare the method pointer like this instead:
// or whatever parameter type Move() actually uses...
void (Excel::_Worksheet::*pMove)(tagVARIANT, tagVARIANT) = &Excel::_Worksheet::Move;
Then, to actually call pMove(), you would have to do something like this:
Excel::_WorksheetPtr spXlSheet = ...;
(spXlSheet.Get()->*pMove)(...);

C++ - Smart Pointers - Passing derived class shared pointer to base through template

I have the following and having difficulty resolving the error please help.
i have the following class as template definition somewhere.
template<class ConcreteHandlerType>
class SomeAcceptor: public ACE_Acceptor<ConcreteHandlerType, ACE_SOCK_Acceptor>
In some other file, i initialize this class in the constructor
class initialize {
typedef SomeAcceptor<BaseClassSomeHandler> baseAcceptor_t;
typedef SomeAcceptor<DerivedClassSomeHandler> derivedAcceptor_t;
boost::shared_ptr<baseAcceptor_t;> mAcceptor;
boost::shared_ptr<derivedAcceptor_t;> mDerivedAcceptor;
bool HandleAcceptNotification(BaseClassSomeHandler& someHandler);
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
}
Error i get is
error: no matching function for call to `boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)'common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:160: note: candidates are: boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(const boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >&)
common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:173: notboost::shared_ptr<T>::shared_ptr() [with T = SomeAcceptor<BaseClassSomeHandler>]
I also tried overloading the function with
bool HandleAcceptNotification(DerivedClassSomeHandler& someHandler);
but because mAcceptor is of type SomeAcceptor BaseClassSomeHandler, i get this error, but to fix this.
I guess i need to cast it somehow, but how to do it?
i tried doing like below inside the constructor and it didn't work
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor = mDerivedAcceptor; // Error here
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
From your code, it looks like you want mAcceptor to be assigned NULL (0), if that is the case you don't need to initialize it at all, as the default constructor will take care of that. But, since you call a function on that (NULL) pointer immediately, its not immediately clear exactly what you want to do.
If you want mAcceptor and mDerivedAcceptor to point to the same (shared) object and assuming DerivedClassSomeHandler is derived from BaseClassSomeHandler, this is a situation where you should use boost::shared_static_cast, as described here.
There's also some good information in this apparently related question.
The error is due to the mAcceptor(0) in
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
The smart_ptr default constructor assigns the wrapped ptr to NULL, so leave out mAcceptor(0) from the initialization list.
boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)
It's yelling at you that there's no constructor that accepts an int.
Just use: mAcceptor()

Syntax for std::binary_function usage

I'm a newbie at using the STL Algorithms and am currently stuck on a syntax error. My overall goal of this is to filter the source list like you would using Linq in c#. There may be other ways to do this in C++, but I need to understand how to use algorithms.
My user-defined function object to use as my function adapter is
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
bool operator()(SOURCE_DATA * test, SOURCE_TYPE ref)const
{
if (ref == SOURCE_All)
return true;
return test->Value == ref;
}
};
And in my main program, I'm using as follows -
typedef std::list<SOURCE_DATA *> LIST;
LIST; *localList = new LIST;;
LIST* msg = GLOBAL_DATA->MessageList;
SOURCE_TYPE _filter_Msgs_Source = SOURCE_TYPE::SOURCE_All;
std::remove_copy(msg->begin(), msg->end(), localList->begin(),
std::bind1st(is_Selected_Source<SOURCE_DATA*, SOURCE_TYPE>(), _filter_Msgs_Source));
What I'm getting the following error in Rad Studio 2010. The error means "Your source file used a typedef symbol where a variable should appear in an expression. "
"E2108 Improper use of typedef 'is_Selected_Source'"
Edit -
After doing more experimentation in VS2010, which has better compiler diagnostics, I found the problem is that the definition of remove_copy only allows uniary functions. I change the function to uniary and got it to work.
(This is only relevant if you didn't accidentally omit some of your code from the question, and may not address the exact problem you're having)
You're using is_Selected_Source as a template even though you didn't define it as one. The last line in the 2nd code snippet should read std::bind1st(is_Selected_Source()...
Or perhaps you did want to use it as a template, in which case you need to add a template declaration to the struct.
template<typename SOURCE_DATA, typename SOURCE_TYPE>
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
// ...
};
At a guess (though it's only a guess) the problem is that std::remove_copy expects a value, but you're supplying a predicate. To use a predicate, you want to use std::remove_copy_if (and then you'll want to heed #Cogwheel's answer).
I'd also note that:
LIST; *localList = new LIST;;
Looks wrong -- I'd guess you intended:
LIST *locallist = new LIST;
instead.

Swig C++ Lua Pass class by reference

I don't know why I'm having a hard time with this. All I want to do is this:
class foo {
public:
foo(){}
~foo(){}
float a,b;
};
class foo2 {
public:
foo2(){}
foo2(const foo &f){*this = f;}
~foo2(){}
void operator=(const foo& f){
x = f.a;
y = f.b;
}
float x,y;
};
/* Usage(cpp):
foo f;
foo2 f2(f);
//or using the = operator
f2 = f;
*/
The problem I'm having is that, after swigging this code, I can't figure out how to make the lua script play nice.
/* Usage(lua)
f = example.foo()
f2 = example.foo2(f) --error
*/
The error I get is "Wrong arguments for overloaded function 'new_Foo2'":
Possible c/c++ prototypes are:
foo2()
foo2(foo const &)
The same thing happens if I try and use do f2 = f. As I understand it everything is stored as a pointer so I did try adding an additional constructor that took a pointer to foo but to no avail.
In the copy constructor you have the reference operator in the wrong place, put it after 'foo'. As your code stands it doesn't compile, at least not for me on VS 2008.
Edit: I see, thanks for the update. Well I'm not particularily familiar with LUA, but I know when porting from C++ to C# there are a few things that change when it comes to references. So my only idea would be if you need to explicitly show that you are passing a variable by ref/const ref. Ie. in C# to pass by ref in a function call you need:
int a = 10;
foo(ref a);
So something similar to this in LUA might cause the errors you show.
God only knows what SWIG is doing. My advice is to bite the bullet and use Lua's C API, which also works with C++. It's not that hard to learn, and you'll be able to overload the foo2 method exactly the way you want. Good examples can be found in Roberto Ierusalimschy's book Programming in Lua; you can get the previous edition free online.
N.B. Since the API is C, it doesn't know from reference parameters. Your Lua userdata object should contain a pointer to the C++ object of class foo2.
Along the lines of the suggestion to use Lua's native C API, but since you're in C++, try out Luabind. It works very well once you get the hang of it. If you do try it be sure to get the latest version--it's actively maintained and getting better all the time.
If you make the lua interface with swig try this instead:
foo2(const foo* f){*this = *f;}
swig has some problems with the reference types but make the automatic conversion from pointers without problems.
I think that the const reference is the problem in swig here
You can tell SWIG how to convert the internal pointer representation to a const reference using a typemap:
%typemap(in) const Foo&
{
if(!SWIG_IsOK(SWIG_ConvertPtr(L,$argnum, (void**)$1, $1_descriptor,1)))
{
SWIG_fail;
}
}
This should generate code that looks something like this in your wrap.cpp file:
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_Foo,1)))
{
SWIG_fail;
}
result = new Foo2(((Foo const &)*arg1);
SWIG_arg=0;
SWIG_Lua_NewPointerObj(L, result, SWIGTYPE_p_Foo2, 1); SWIG_arg++;