C++ variable declaration is treated like a function declaration - c++

The question is fairly theoretical, though it's interesting what makes MS VS2010 treat the following variable declaration (inside main) like a function declaration:
typedef std::shared_ptr<asymm::PrivateKey> PrivateKeyPtr;
...
void main()
{
...
maidsafe::dht::PrivateKeyPtr pk(); // I'm trying to init variable here, though it thinks it's function declaration
kNode->node()->Store(key, value, "", ttl, pk, std::bind(&StoreCallback, args::_1, key, ttl));
}
It throws the following exception:
Error 5 error C2664: 'maidsafe::dht::Node::Store' : cannot convert parameter 5 from 'maidsafe::dht::PrivateKeyPtr (__cdecl *)(void)' to 'maidsafe::dht::PrivateKeyPtr' C:\Projects\MaidSafe-DHT\src\maidsafe\dht\demo\demo_main.cc 286 1 KademliaDemo
While the following lines work like a charm:
maidsafe::dht::PrivateKeyPtr pk = maidsafe::dht::PrivateKeyPtr();
kNode->node()->Store(key, value, "", ttl, pk, std::bind(&StoreCallback, args::_1, key, ttl));

Declare it without the ():
maidsafe::dht::PrivateKeyPtr pk;
Unfortunately, for primitive types that gives you an uninitialized value, but in C++11 you can value initialize with {}:
maidsafe::dht::PrivateKeyPtr pk{};
For a related parsing issue, see the c++ most vexing parse.

Related

std::bind: error: too few arguments to function call, single argument was not specified

I have the following code:
void MyClass::create_msg(MyTime timestamp) {
// do things here ...
}
and I tried to create a std::bind for the above function:
MyMsg MyClass::getResult(MyTime timestamp) {
// do things here ...
std::bind(create_msg(), timestamp);
// do things ...
}
But got the following error:
error: too few arguments to function call, single argument 'timestamp' was not specified
std::bind(create_msg(), timestamp);
~~~~~~~~~~ ^
MyClass.cpp:381:1: note: 'create_msg' declared here
void MyClass::create_msg(MyTime timestamp) {
^
1 error generated.
What did I do wrong in this case? Thanks!
By the way, same error if I do:
std::bind(&MyClass::create_msg(), this, timestamp);
There are three issues here.
First, the argument you're giving to std::bind as your function is currently create_msg(). This means "call create_msg, take whatever result it produces, and pass that in as the first argument to std::bind." That's not what you want - you instead meant "take create_msg and pass it as the first parameter to std::bind." Since create_msg is a member function, you'll need to get a pointer to it like this:
std::bind(&MyClass::create_msg, /* ... */)
That will address one issue, but there's another one that will then pop up. When you use std::bind with a member function pointer, you need to prove std::bind with an extra parameter corresponding to the receiver object to use when calling that member function. I believe that in your case you want the current object to be the receiver, which would look like this:
std::bind(&MyClass::create_msg, this, timestamp)
That should work properly.
However, one could argue that there's a third issue here - rather than using std::bind, why not just use a lambda expression?
[timestamp, this] { create_msg(timestamp); }

C++ Changing the values of members of a const struct [duplicate]

This question already has answers here:
C/C++ changing the value of a const
(18 answers)
Closed 8 years ago.
I have a struct which is defined in types.h with the following code:
struct data_Variant {
FlightPlanSteeringDataRecord steeringData;
FlightPlanType flightPlan : 8;
MinitoteLegDataType legDataType : 8; // discriminent, either current or amplified
unsigned spare : 16;
union {
// currentLeg =>
CurrentLegDataRecord currentLegData;
// amplifiedLeg =>
AmplifiedLegDataRecord amplifiedLegData;
} u;
};
I am then trying to pass an instance of that struct as a parameter to a function in a C++ source file called dialogue.cpp:
void dialogue::update( const types::data_Variant& perfData){
...
}
I now want to change the value of some of the members of that struct inside this update() function. However, if I try doing this as I usually would, i.e.
perfData.etaValid = true;
I get a compile error which says: "C2166: l-value specifies const object". As I understand, this is because perfData has been declared as a constant variable. Am I correct in thinking this?
Since I didn't write this part of the code, but only want to use it to update the value displayed on the GUI, I don't really want to change the perfData variable by removing the const keyword, in case I break something else. Is there any way to change the value of a variable that has been declared as const?
I have tried declaring the same struct variable in another part of the code, without using the const keyword, to see if I can change the values of some of its members there... i.e. in Interface.cpp, I have added the following code to a function called sendData():
types::data_Variant& perfData;
perfData.steering.etaValid = true;
perfData.steering.ttgValid = true;
However, I now get the following compile errors on these lines:
error C2653: 'types' is not a class or namespace name
error C2065: data_Variant: undeclared identifier
error C2065: 'perfData': undeclared identifier
error C2228: left of '.steering' must have class/ struct/ union
Is there a way of updating the values of this struct? If so, how should I do it, and what am I doing wrong here?
I have added the following function to the dialogue.cpp source file, as suggested in the answer:
void dialogue::setFPTTGandETAValidityTrue(
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& perfData)
{
SESL_FUNCTION_BEGIN(setFPTTGandETAValidityTrue)
perfData.steeringData.fpETAValid = true;
perfData.steeringData.fpTTGValid = true;
SESL_FUNCTION_END()
}
You could add a wrapper for yourself.
void myupdate(dialogue& dia, types::data_Variant& perfData)
{
perfData.etaValid = true;
dia.update(perfData);
}
Then call myupdate() instead of dialogue::update().
You declare
void dialogue::update( const types::data_Variant& perfData){
...
}
that const is a declaration of you saying: "I won't modify the referenced object in this function". If you want to modify it in dialogue::update you have to remove the const keyword. Wrapping is not a solution, in my opinion, makes the code harder to maintain. Also I vote against remove const with const_cast.
The correct solution is to remove const from method declaration if you want to modify the referenced object inside that function.

Enumeration type as return value in soapcpp2

I'm creating a web service using gSoap, in the header file I have few method definitions that their return type is enum value.
When I'm executing the soapcpp2.exe tool and passing with the header file I'm getting this error:
sample.h(20): syntax error
sample.h(21): Syntax error: input before ; skipped
In addition, if I have more than one method with the enum as the return value I'm getting this warning:
**WARNING**: Duplicate declaration of 'sample_status_____' (already declared at li
ne 31), changing conflicting identifier name to new name sample_status______'. Note: this problem may be caused by importing invalid XML schemas (detected at line 38 in sample.h)
My header file looks such like:
// enum definition
enum status {ok, error};
// method definition
status ns_calc(int a, int b);
Is it a limitation with soapcpp.exe?
The header file you are writting has to follow some gSoap conventions. Therefore the output of the function has to be the last argument. From the documentation:
By convention, all parameters are input parameters except the last. The last parameter is always the output parameter. A struct or class is used to wrap multiple output parameters, see also Section 7.1.9. This last parameter must be a pointer or reference. By contrast, the input parameters support pass by value or by pointer, but not pass by C++ reference.
The relevant part in the header file would look like:
enum ns__status { ok, error };
int ns__calc(xsd__int a, xsd__int b, enum ns__status& out);
Note that this example explicitly uses XML-Schema (xsd__) types, this practice is advised to improve interoperability. The relevant part in the cpp file would look like:
int ns__calc(struct soap* soap, xsd__int a, xsd__int b, enum ns__status& out)
{
// do something with 'a' and 'b' and set 'out'
out = ...
return SOAP_OK;
}

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.