c2664 in Visual Studio 2012 when using make_pair - visual-c++

I dig up an old project and wanted to compile it, but received several errors, a few of those being a c2664:
error C2664: 'std::make_pair' : cannot convert parameter 1 from 'CUser *' to 'CUser *&&'
error C2664: 'std::make_pair' : cannot convert parameter 1 from 'unsigned long' to ' unsigned long &&'
The relevant code parts are:
//typedef for the userdata map
typedef std::map<unsigned long, std::pair<CUser*,userstatus*>> UserDataMapType;
//...
Inc::incret CUserManager::AddUser(unsigned long ID, CUser* pUser, userstatus* pUserStatus)
{
//...
std::pair<UserDataMapType::iterator, bool> ret = m_mapUserData.insert(std::make_pair<unsigned long, std::pair<CUser*, userstatus*>>(ID, std::make_pair<CUser*, userstatus*>(pUser, pUserStatus)));
//...
}
I tried to make the function parameters const, but that did not help.
It did compile just fine in VS2010.
Please help me find what causes this and how to solve it.

make_pair() has been changed in VS2012 to support a new C++11 feature called move semantics and I suspect that explicitly specifying the types for make_pair() is getting in the way.
Remember that make_pair() does not need any template parameters to be explicitly specified. It deduces them from the type of each argument.
Try removing the explicit template arguments from both calls to make_pair() like so...
std::pair<UserDataMapType::iterator, bool> ret = m_mapUserData.insert(std::make_pair(ID, std::make_pair(pUser, pUserStatus)));
Explicitly providing them like this would have worked fine pre-VS2012 because of a new C++11 feature added called move semantics. You'll want to read up on that subject later since you have a shiny new compiler that supports it.

Related

Why does UDT / struct with missing type information cause silent launch failure in vb6?

Consider this registered type library in a DLL:
[uuid(…), version(1.0)]
library structLib
{
importlib("stdole2.tlb");
[uuid(…)]
typedef struct MyStruct
{
BSTR m_sStr;
} MyStruct;
};
In vb6 I can reference this type library and use the UDT / struct in a compiled exe (simple form with a button), named a.exe:
Private Sub Command1_Click()
Dim obj As structLib.MyStruct
obj.m_sStr = "Hello"
MsgBox obj.m_sStr
End Sub
When I remove the struct from the type library and recompile it, the previously compiled a.exe still works, even though the struct definition is no longer present. I assume this succeeds because the definition is embedded into the executable during the vb6 compilation process.
However, things work differently when I compile the following vb6 code against the unmodified type library (struct included) into a new executable, named b.exe:
Private Sub Command1_Click()
Dim obj As structLib.MyStruct
obj.m_sStr = "Hello"
MsgBox obj.m_sStr
Dim vt as Variant
vt = obj
MsgBox vt.m_sStr
End Sub
Notice the assignment of the struct to a Variant.
When I remove the struct definition from the type library once again, recompile it, and try to run the previously compiled b.exe, the program silently fails as the form won't even show up. At minimum, I expected
Starting the executable loads the form.
Clicking the button throws an error, due to assigning the struct with missing type information to the Variant.
For the record, I have tried to reproduce this behavior in C++:
structLib::MyStruct obj;
obj.m_sStr = SysAllocString(L"Hello");
MessageBox(GetActiveWindow(), obj.m_sStr, obj.m_sStr, MB_OK);
ATL::CComVariant vtRec;
ATL::CComPtr<IRecordInfo> piRecInfo;
HRESULT hr = GetRecordInfoFromGuids(__uuidof(structLib::__structLib), 1, 0, 0, __uuidof(structLib::MyStruct), &piRecInfo);
vtRec.pRecInfo = piRecInfo;
vtRec.pvRecord = &obj;
PVOID pvItem = vtRec.pvRecord;
CComVariant vtStr;
hr = piRecInfo->GetField(pvItem, L"m_sStr", &vtStr);
MessageBox(GetActiveWindow(), vtStr.bstrVal, vtStr.bstrVal, MB_OK);
Here, the C++ client runs and GetRecordInfoFromGuids() correctly returns
0x8002802b (Element not found)
when the struct definition is missing in the type library.
Is this behavior in vb6 by design? What's the cause? And is it possible to start the vb6 executable and catch error information, even when extracting type information of a referenced struct fails?
Is this behavior in vb6 by design?
I don't think so.
What's the cause?
When you assign a IDL structure to a VARIANT, the [uuid] attribute is intrinsically used. As it doesn't exist anymore, you get an exception.
That's what you do when calling GetRecordInfoFromGuids in C++, you provide explicitely the uuid of the IDL structure __uuidof(structLib::MyStruct).
And is it possible to start the executable even when extracting type
information of a referenced struct fails?
I see 2 possibilities to achieve this goal:
use late binding instead of early binding, and check the reference
handle the exception which is thrown

Inline C Varnish (VCL_deliver)

I am using Varnish 4.0.
My backend is adding to some responses an http header "x-count"
I would like to log the value of "x-count" into a file with a line break.
I assumed i should do it in VCL deliver.
Here is what i have so far :
sub vcl_deliver {
if (resp.http.x-count-this:) {
set resp.http.X-infodbg = "xx";
C{
FILE *fp;
fp = fopen("/tmp/test.txt", "w+");
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
fputs("\n", fp);
fclose(fp);
}C
}
}
Of course it doesnt work and there is a couple of errors ..
./vcl.gK2lu7uM.c: In function ‘VGC_function_vcl_deliver’:
./vcl.gK2lu7uM.c:1049:22: error: ‘sp’ undeclared (first use in this
function) ./vcl.gK2lu7uM.c:1049:22: note: each undeclared identifier
is reported only once for each function it appears in
./vcl.gK2lu7uM.c:1049:5: error: passing argument 2 of ‘VRT_GetHdr’
makes pointer from integer without a cast [-Werror]
./vcl.gK2lu7uM.c:330:7: note: expected ‘const struct gethdr_s *’ but
argument is of type ‘int’ ./vcl.gK2lu7uM.c:1049:5: error: too many
arguments to function ‘VRT_GetHdr’ ./vcl.gK2lu7uM.c:330:7: note:
declared here
I have to say that i simply copy/pasted "sp" from some examples, but i have no idea where it comes from (i suppose the inline C was in a different context and therefore it was declared there but not in vcl_deliver)
So the probably undocumented differences between Varnish 4 and 3 in the above examples are :
VRT_GetHdr is now VRT_GetHdr(context, struct gethdr_s)
sp doesn't exist, but there is a "ctx" variable
Found this, there :
http://jan.bogutzki.de/Artikel/395/set-ttl-in-varnish-4.html
char *stuffid;
const struct gethdr_s hdr = { HDR_BERESP, "\015x-count-this:" };
stuffid = VRT_GetHdr(ctx, &hdr);
And now a different story: Varnish is crashing as soon as the backend sends back "count-this", but that is a different problem :p (my crappy C code probably)
I don't have Varnish 4.0 handy to test this out, but I was able to get your example working with Varnish 3.0. When I tried the VCL as is, I wasn't getting the exact error you are though. The first change:
if (resp.http.x-count-this:) {
needs to be:
if (resp.http.x-count-this) {
The colon should be left off of the header name when referred to this way. Next:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
needs to be:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\015x-count-this:"), fp);
The length value in that string needs to be in octal for some reason, and 13 in octal is 15. Making those changes got this to work for me. That being said, you many want to look into using open and fcntl instead of fopen since without file locking I'm not sure what the effect of multiple requests contending for that file would be.

redefinition of default parameter error without redefining

I am getting a strange set of error in my Visual Studio 2010 compiler.
I am getting the errors of
error C2572: redefinition of default parameter
error C2011: 'class' type redefinition
I have checked thoroughly and I know very well that in the function definition, I have not given the default parameter values and I have given default parameter value only in function prototype in the header file.
Also, I am very much sure that no two class has been given the same class name.
Please can anybody tell me what could be the other reasons for getting these set of errors?
I have not got the exact reason why it was happening, but I have overcome it by using some simple techniques.
I used function overloading concept to avoid default parameter list. It will cause in duplication of code, but it has proved to be very effective.
So something like this
void myFunction( int, char * = '\0', char * = '\0' );
would become something like this
void myFunction( int );
void myFunction( int, char * );
void myFunction( int, char *, char * );
In this example, code is getting duplicated two times but it seems to be only work around solution.
Next, for the strange class type redefinition error, I was instantiating the class variable in many files. So, I removed that feature of instantiation everywhere and went with global variable something like this.
File named as myHeader.h
#include "myFile.h"
myClass myObj;
And in all the other files
#include "myHeader.h"
myObj.function1( );
myObj.function2( );

how visual studio tell c++ and c?

As the title says,does the visual studio distinguish these two files by their suffix?.c or .cpp?
I also have another question.At first,I stated the program like this:
int main(int argc, char **argv)
{
LARGE_INTEGER TimeStart;
LARGE_INTEGER TimeEnd;
QueryPerformanceCounter(&TimeStart);
static double Freq;
static int getfreq;
double mu,om;
double *v;
int it,i,j;
....
}
but it brings out many problems:
1>sor2d.c(23): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(24): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(25): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(26): error C2143: syntax error : missing ';' before 'type'
23 ling points to "static double Freq;"
but if I put "QueryPerformanceCounter(&TimeStart);" after the data allocation,the compiler can succeed.Could someone tell me why this happened,was is just because of my carelessness of omitting something or ignorance...?
In C, all variables must be declared before calling any methods.
Visual Studio will, by default, compile .C files as C. You can override this.
In C89, you must declare all of your variables at the top of the code block. You may also initialize them to compile-time constants (literals, macros that expand to literals, the values of variables that have already been initialized, and any operations on the above that can be performed at compile time). You cannot intersperse other types of statements (like function calls) within these declarations.
This limitation was removed in C99 (which is not supported by Visual C++) and C++.

The explicit keyword in MS Visual Studio 4.1

I am implementing a smart pointer class using generics and I wanted to force users of this class to properly construct the smart pointer using syntax such as
MyReference<TestCls>(mytest3))
or
MyReference<TestCls> mytest4(new TestCls());
so I have used the explicit keyword on the CTOR, to prevent this:
MyReference aRef = NULL;
However due to unfortunate circumstances beyond my control, I am working on code that is compiled using the ancient MSVC++ 4.1 compiler. I get the following errors when I include the explicit keyword:
MyReference.h(49) : error C2501: 'explicit' : missing decl-specifiers
MyReference.h(51) : error C2143: syntax error : missing ';' before ''
MyReference.h(52) : error C2238: unexpected token(s) preceding ':'
MyReference.h(52) : error C2059: syntax error : 'int constant'
When I add a #define explicit those errors disappear.
This was a hack on my part, just to get the compiler to ignore the keyword. I'm guessing that this means that explicit is not supported by yon olde compiler.
Can someone confirm this and is there anyone out there with knowledge of a workaround solution for this?
Merci Beaucoups,
Dennis.
This site has a workaround for this, namely:
Unfortunately, older compilers may not
support the use of "explicit", which
could be a headache. If you're stuck
working with an out-of-date compiler
and can't get one that has better
support for the C++ standard, your
best solution may be to take advantage
of the fact that only a single
implicit conversion will take place
for a given value. You can exploit
this by using an intermediate class
that implicitly creates an object of
each type, and then have your main
class implicitly create objects from
that class:
class proxy
{
public:
proxy(int x) : x(x) {} ;
getValue() { return x; }
private:
int x;
};
class String
{
// this will be equivalent of explicit
String(proxy x) { /* create a string using x.getValue(); */ }
}

Resources