type casting when return from function with shared_ptr - c++

std::shared_ptr<AbstractPrinter> parse_input_fiz(char const *input) {
std::shared_ptr<FizPrinter> printer(FizPrinter);
return printer;
}
FizPrinter inherited from AbstractPrinter. And i got next error:
Description Resource Path Location Type could not convert ‘printer’
from ‘std::shared_ptr (*)(FizPrinter)’ to
‘std::shared_ptr’ parser.cc /pdf-i/src line 63 C/C++
Problem
this function one of used in Factory

Did you mean
std::shared_ptr<FizPrinter> printer(new FizPrinter());
Your current code declares a function and the constructor for a shared_ptr takes a pointer.

std::shared_ptr<FizPrinter> printer(FizPrinter);
means "printer is a function with argument FizPrinter".
See question 10.21: http://www.parashift.com/c++-faq-lite/ctors.html

Related

how to deal with a function pointer problem?

i'm implementing a normal function pointer.
so this is the function that i want to call:
WndDyn* Punkt2d::pEditPunkt(WndInfo& wi, Int32 AnzSichtChar, Bool WithUnit,
const DecimalsConf& DecConf)
{
WynDyn_callback Dyncallback;
Dyncallback.AnzSichtChar = AnzSichtChar;
Dyncallback.WithUnit = WithUnit;
Dyncallback.DecConf = DecConf;
return &(DlgZeile(wi)
+ pEditAll(Dyncallback, &pEditFeldX)//pEditFeldX(AnzSichtChar, WithUnit,
DecConf)
+ FntXUnit(2)
+ pEditFeldY(AnzSichtChar, WithUnit, DecConf)
);
}
After defining the function that needs to be called i defined my callee as follow:
WndDyn* pEditAll(WynDyn_callback& Dyncallback, WndDyn* (func_Call)
(WynDyn_callback)) {
return func_Call(Dyncallback);
}
And last of all this is the function that needs to be called using the callee function:
WndDyn* Punkt2d::pEditFeldX(WynDyn_callback Dyncallback) {
return &Edit(pNewStrDataLink(m_x, DLUC_Length, Dyncallback.DecConf),
Dyncallback.AnzSichtChar)
.WithSelAllOnFocus(True);
}
My actuall problem is that my compiler is underlining the function pEditFeldX
in this line pEditAll(Dyncallback, pEditFeldX) in the function pEditpunkt and showing me this Error:
Severity Code Description Project File Line Suppression State
Error C3867 'Punkt2d::pEditFeldX': non-standard syntax; use '&' to
create a pointer to member
Severity Code Description Project File Line Suppression State Error
(active) E0167 argument of type "WndDyn (Punkt2d::)(WynDyn_callback
Dyncallback)" is incompatible with parameter of type "WndDyn
()(WynDyn_callback)"
Because pEditFeldX is a member function you can't just call pEditFeldX(Dyncallback). You must call the function on some Punkt2d object, using e.g. meinPunkt2d.pEditFeldX(Dyncallback).
If you write pEditFeldX(Dyncallback) inside the Punkt2d class then it means (*this).pEditFeldX(Dyncallback). The compiler adds (*this). to save some typing.
A function pointer only points to a function. It doesn't point to a function and an object. It points to pEditFeldX, not meinPunkt2d.pEditFeldX. You must specify the Punkt2d object when you call it.
To remember that a Punkt2d must be specified, a function pointer which points to a member function is declared as this: WndDyn* (Punkt2d::*func_Call)(WynDyn_callback) and called as this: meinPunkt2d.*func_Call(Dyncallback);
If the function pointer is &pEditFeldX then meinPunkt2d.*func_Call(Dyncallback) is the same as meinPunkt2d.pEditFeldX(Dyncallback)
This doesn't apply to static member functions. Static member functions can be used with normal function pointers since no object is required.
It is not quite clear what you are trying to do, but if I understand it right, I think that std::function would be able to solve your problem std::function is able to store anything which can be called, including "half of a function call" like you seem to want. std::bind can make these "half function calls".
You could use them like this:
// in pEditPunkt
pEditAll(Dyncallback, std::bind(&CPunkt2d::pEditFeldX, this, std::placeholders::_1))
// in pEditAll
WndDyn* pEditAll(WynDyn_callback& Dyncallback, std::function<WndDyn* (WynDyn_callback)> (func_Call)
(WynDyn_callback)) {
return func_Call(Dyncallback);
}
First of all i would like to thanks #user253751 for his patient and great support. i would like to share with you how my code look like now:
#include <functional>
// pointer function
WndDyn* pEditAll(WynDyn_callback& Dyncallback, std::function<WndDyn*
(K_WynDyn_callback)>func_Call) {
return func_Call(Dyncallback);
}
//the calle
WndDyn* K_Punkt2d::pEditPunkt( WndInfo& wi, Int32 AnzSichtChar,
Bool WithUnit, const DecimalsConf& DecConf)
{
WynDyn_callback Dyncallback;
Dyncallback.AnzSichtChar = AnzSichtChar;
Dyncallback.WithUnit = WithUnit;
Dyncallback.DecConf = DecConf;
return &(DlgZeile(wi)
+ pEditAll(Dyncallback,
std::bind(&Punkt2d::pEditFeldX, this,
std::placeholders::_1))//pEditFeldX(AnzSichtChar, WithUnit,
DecConf)
+ FntXUnit(2)
+ pEditFeldY(AnzSichtChar, WithUnit, DecConf)
);
}

Redirecting stdout to LCD: pointer of member class

FILE *LCD_stdout = new FILE();
int (*ptr)(char, FILE *) = ROBOT::__LCD_putchar;
fdev_setup_stream(LCD_stdout, ptr, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
gives me error:
In member function 'SUBSYS_OPENSTAT ROBOT::LCD_open()':
LCD.cpp:108: error: argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)'
I've looked at a number of solutions through Stack Overflow and whatnot. .* doesn't resolve it, tried assigning a pointer of a pointer, and I feel I'm likely not going to be resolve it without resolving misconceptions.
The compiler error tells you exactly what's wrong:
argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)
...because pointers to member functions aren't compatible with pointers to non-member functions, for a couple of reasons.
One option is to create a separate free function but this depends on where the ROBOT object resides. For example if you have a global ROBOT object you could do the following
ROBOT globalRobot;
int callback(char c, FILE* f)
{
return globalRobot.__LCD_putchar(c, f);
}
FILE *LCD_stdout = new FILE();
fdev_setup_stream(LCD_stdout, callback, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
If there is only going to be one robot object and it is a member variable of another class change globalRobot to be a pointer and set it after the ROBOT object has been created (ROBOT's constructor maybe)
This is untested as I don't know the innards of ROBOT but everything looks ok.

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()

issue returning CArray

I am trying to return a CArray from a function and trying to call the function from another class
short ListMaker::RetArray(CString szName, CArray<CString, CString&> &szarr_Names) {
szarr_Names.Add(szName);
return 0;
}
int main() {
//..
CArray<CString, CString&> myArray;
ListMaker LM;
short nCode = LM.RetArray(L"Name", myArray);
//..
}
I am getting following errors:
Error 1 error C2664: 'RetArray' : cannot convert parameter 2 from 'CArray<TYPE,ARG_TYPE>' to 'CArray<TYPE,ARG_TYPE>'
Error 2 error C2511: 'short RetArray(CString,CArray<TYPE,ARG_TYPE> &)' : overloaded member function not found in 'ListMaker'
Please tell me the correct way to define and access the return value of the CArray.
Erm, frist of all if RetArray is a member of ListMaker class and you call it from main(), you cannot call it like this: short nCode = RetArray(L"Name", myArray);
If RetArray is a static member, use short nCode = ListMaker::RetArray(L"Name", myArray);. It it's non-static, use instance, short nCode = listMakerInstance.RetArray(L"Name", myArray);.
Check your header file for RetArray declaration in ListMaker class. It might differ from the implementation in your cpp file, hence you get the C2511 error.
You cannot store a reference in an array type, and CArray is to be absolutely avoided at all costs as it uses memcpy to resize and not copy construction, breaking your code the instant you need something with a useful constructor.
I think the problem is in CString&, try using CArray<CString, LPCTSTR> instead.

regarding encryption method

i am using encrypt function of cryptography api(fun declared as virtual)
//fun declaration
TBool EncryptL(const TDesC8 &aInput, TDes8 &aOutput);
//function calling
TBuf8<10> text;
TBuf8<10> cipher;
text.Copy(_L("Hello"));
iEncryptor.EncryptL(text,cipher); it shows error expression syntax error
//fun definition
TBool CRSAAlgo::EncryptL(const TDesC8 &aInput,TDes8 &aOutput)
{
if(iEncryptor)
{
TInt len = iEncryptor->MaxInputLength();
}
}
i want to know what is exact problem
The main issue here, the reason your compiler complains is that you are using iEncryptor as an object or a reference, while it probably is a C++ pointer.
To move to the next stage, try using:
iEncryptor->EncryptL(text,cipher);
As you did not post the exact error message you get from the compiler I have to guess.
I assume the problem is that the EncryptL function you show expects to get arguments of type TDesC8 and you pass a TBuf8<10> to it. Unless TDesC8 were a typedef to TBuf8<10> these are different and therefore for the compiler incompatible types.
Ypou are also using iEncryptor once as a pointer: iEncryptor->MaxInputLength(); and at the location where you see the error as an object: iEncryptor.EncryptL(text,cipher);. Only one form can be correct. As we don't have more code from you I don't know which, but given the fact that the latter has the error I suspect the latter.