Error C2668 in bind while porting from VS2008 to VS2013 - c++

I'm trying to port my code from VS2008 to VS2013 and I'm getting some errors with std::bind.
The errors say error C2668: 'bind' : ambiguous call to overloaded function.
Here's some code:
// Relevant prototypes:
class CLineaPlanta:public SomeBase { /*...*/ };
int SomeBase::TipoLinea()const;
void SomeBase::TipoLinea(int val);
// function paramater: const std::shared_ptr<CLineaPlanta>& lineasBuscar
// function parameter: int tipoLinea;
std::shared_ptr<CLineaPlanta> lineas;
std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
std::back_inserter(lineas),
bind(std::not_equal_to<int>(), bind(&CLineaPlanta::TipoLinea, _1), tipoLinea));
This code worked in Visual Studio 2008, but gives the mentioned error in Visual Studio 2013.
Obviously, the compiler's having a hard time figuring out which version of TipoLinea() I'm trying to call. If I rename the getter version to getTipoLinea, the error goes away.
Just in case it is relevant, SomeBase is non-abstract and derives from CObject (not really sure why) and from an interface not related to this part of the code.
Can anyone explain why VS2008 doesn't have any problem with this and how to prevent it (other than by renaming the function, of course)?

I have no idea why this code ever worked in VS2008. It was probably a consequence of 2008's bind being implemented as a macro-based variadics emulation where bind had several overloads for each number of arguments being passed, one of them expecting the first argument to be a pointer to member function with the same number of arguments. This would allow the compiler to disambiguate because you pass one bound argument to bind, so it knows the function argument must have one parameter.
In VS2013, true variadics are used, but this probably means that the type of the first argument is more generic and so the compiler can no longer disambiguate. To make this compile, you need to explicitly cast the member pointer:
std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
std::back_inserter(lineas),
bind(std::not_equal_to<int>(),
bind(static_cast<int (SomeBase::*)() const>(&CLineaPlanta::TipoLinea),
_1),
tipoLinea));
But as Neil Kirk said, rewriting to a lambda is easier:
std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
std::back_inserter(lineas),
[tipoLinea](const std::shared_ptr<CLineaPlanta>& linea) {
return linea->TipoLinea() != tipoLinea;
});

Related

Switching from MSVC14 to MSVC16 leads to "compiler is out of heap space (C1060)" error

I'm trying to switch from the Visual Studio 14 2015 compiler to Visual Studio 16 2019 to compile my project (also tried Visual Studio 15 2017, but that resulted in the same issues). I'm using irrequietus/typestring, which worked perfectly fine with the old compiler but leads to errors now.
Here's a class that's supposed to be used with a typestring:
// my_custom_class.h
template<typename T>
class MyCustomClass
{
public:
static bool compareTheTypestring(const std::string& other) const {
return std::strcmp(data(), other.c_str()) == 0;
}
}
This is how I use the class:
// use_it.cpp
#include "typestring.hh"
#include "my_custom_class.h"
typedef MyCustomClass<typestring_is("Foo")> FooCompare;
Which spits out the following error in typestring.hh:
compiler is out of heap space (C1060).
And more errors in use_it.cpp:
irqus::typeek: no matching overloaded function found (C2672)
Failed to specialize function template 'unknown-type irqus::typeek(irqus::typestring<C...>)'
cannot deduce template arguments for MyCustomClass
The repository contains a similar issue, but the maintainer doesn't seem to reply. I tried to find alternative typestring implementations, but couldn't. Can anyone help me to resolve this, please?
This issue has already been reported in january, with 0 responses since then. It seems the library is no longer being updated... maybe look for an alternative solution
You should really add the details of what you are trying to do into your question. Has to read through the external library before I understood what it is you are trying to achieve. My best suggestion would be: look for an alternative. There are other ways for compile-time strings. Template arguments are probably not the best answer.
If you really want to use the template argument strings, you'll have to fix it yourself. The library was probably relying on undefined behavior. So it's broken now.
I was trying it, but it's not very straight forward. You'll probably need to use the charizing operator in macro's to split the string, and then put the chars into a tuple-type...
template<char c>
class CharType {
public:
static constexpr char Char = c;
};
using FooString = std::tuple<CharType<'F'>, CharType<'o'>, CharType<'o'>>;
Or something like that.

Passing empty QString by reference

I have a method that has this signature
void SetFoo(QString& foo);
and I'm trying to pass an empty string inline, but none of the following compile
SetFoo("");
SetFoo(QString(""));
(error: no matching function for call to ‘MyClass::SetFoo(QString)’)
but if I create a variable like this, it works.
QString emptyFoo = "";
SetFoo(emptyFoo);
Is there not a way to call the method without creating a variable explicitly?
NOTE:
Everything seem to work in windows environment with using vc++ compiler but I encounter the above mentioned compilation error in linux environment using g++.
You can create a global object as a const QString nullStr() and use it everywhere- Somewhat similar to Null Object Pattern.
Alternatively as billz mentions, a const reference to a temporary can exist, so making it const Qstring& will enable the first 2 versions
Regardless, you should change the reference to const Qstring& if you dont intend to modify it.
To bind a reference to a temporary object, you need const qualifier, if QString constructor takes char* input, try:
void SetFoo(const QString& foo);
It makes sense to pass a reference to outlived variable to SetFoo only:
void SetFoo(QString& foo);
QString s;
SetFoo(s);
.
NOTE: Everything seem to work in windows environment with using vc++ compiler but I encounter the above mentioned compilation error in linux environment using g++.
VisualStudio is famous(good or bad way) for its C++ extentions, your code compiles on VS doesn't mean it's the C++ standards. The better way is to turn on compile warning(level 4) when you write code, it should give you a warning for binding a reference to temporary object.
Also lookup C++ standard, lookup compiler manuals to make sure your code is portable.

strange error in passing pointers (*&) in constructor

i'm not a c++ guru at all, and i've tried to replicate this error in variuos little trials. the fact is that when i do a little program with 2 o 3 classes with what i wanto to do, there is no error. but in the main applicaiton i'm tring to write the error persist even if i've tried a lot of (even nonsense) solutions.
the problem is that i have a main class that instantiate some resources (as pointers) and a strategy pattern that istantiate different concrete behaviours that take in constructors thoose resources.
in main app, init():
device = new Kinect();
controls = new Gui();
UserPositionBehaviour = new UserPositionBehaviour(device, controls);
and, behaviour constructor:
UserPositionBehaviour(Kinect * device, Gui * controls);
this is the error:
src/App.cpp:30: error: no matching function for call to ‘UserPositionBehaviour::UserPositionBehaviour(Kinect*&, ofTrueTypeFont*&, ofxGui*&)’
src/UserPositionBehaviour.h:15: note: candidates are: UserPositionBehaviour::UserPositionBehaviour(Kinect*, ofxGui*, ofTrueTypeFont*)
src/UserPositionBehaviour.h:13: note: UserPositionBehaviour::UserPositionBehaviour(const UserPositionBehaviour&)
eh?? hei, what is happening? i'm passing pointers, not *& (that i don't event know how to read)
some advice?
i've tried to replicate the error with a simple case builds only on couts but there are no problems so mayebe there is some error hidden somewhereelse..
According to the error message, you're calling the constructor with three arguments, not two, and you've got the last two the wrong way round.
If that's the real error message, then your code probably looks like:
UserPositionBehaviour = new UserPositionBehaviour(device, font, controls);
// ^^^^ ^^^^^^^^
and should be:
UserPositionBehaviour = new UserPositionBehaviour(device, controls, font);
// ^^^^^^^^ ^^^^
If your code really does look like what you've posted, and gives that error message, then something really weird is happening; in that case, please post a complete compilable example so we can investigate further.
You can ignore the extra &s in gcc's error message: it's a slightly odd way of saying that it's looking for functions that take their arguments by either value or reference.
The code that causes the error passes three arguments (not two as you think), and it has the last two in the wrong order. You must be looking at the wrong version of the source files, or something like that.
Check for silly things like out-of-date copies of src/UserPositionBehaviour.h and src/App.cpp lying around, that you might be looking at instead of looking at the version the compiler is actually compiling. Or maybe you're using pre-compiled headers, and something has gone wrong there.
The error message for a not-found function will usually look like that. The Foo *& is type "reference to pointer to Foo", and it just means that your argument expression is an lvalue pointer-to-Foo. That call could match a function that takes a pointer by value, or a function that takes a pointer by reference. The compiler hasn't found either, but it has to pick something for the error message, and your compiler picks that one. If your call contained the argument expression device+0 instead of device, then it would not be eligible to pass by non-const reference (because the result of device+0 is a temporary), and the error message wouldn't have the &.
The code should compile if you truly have the constructor
UserPositionBehaviour(Kinect * device, Gui * controls);
defined, which, according to the compiler, you don't:
src/UserPositionBehaviour.h:15: note: candidates are:
UserPositionBehaviour::UserPositionBehaviour(Kinect*, ofxGui*,
ofTrueTypeFont*) src/UserPositionBehaviour.h:13: note:
UserPositionBehaviour::UserPositionBehaviour(const
UserPositionBehaviour&)
The *& simply means you pass the pointer by reference - i.e. it can be modified inside the constructor.

Using enum parameter in functions

I'm working on Windows, in C++ with Visual Studio.
I have a class that has a:
enum algorithmStatus { LOADING, DETECTION, TRACKING, LOST };
In the declaration I want to use a setter and getter to change the status, something like:
void MyStatusClass::setAlgorithmStatus(algorithmStatus newStatus)
{
//_Status = newStatus;
//_Status = MyStatusClass::algorithmStatus::LOADING;
}
But I can't compile because I get:
Error 5 error C2511: 'void MyStatusClass::setAlgorithmStatus(MyStatusClass::algorithmStatus)' : overloaded member function not found in 'Nft_Status' c:\MyStatusClass.cpp 197
How can I do that setter correctly?
EDIT:
In header is already declarated:
void setAlgorithmStatus(MyStatusClass::algorithmStatus newStatus);
and:
void setAlgorithmStatus(algorithmStatus newStatus);
In cpp the function is declared just i write on top.
SOLVED
The problem was i used a MyStatusClass::algorithmStatus in the constructor, you don´t need to use the MyStatusClass::, and its advisable don´t use it if you don´t need it.
The MSDN documentation for error code C2511 gives you a good list to lookout for:
identifier : overloaded member function not found in class
No version of the function is declared with the specified parameters. Possible causes:
Wrong parameters passed to function.
Parameters passed in wrong order.
Incorrect spelling of parameter names.
Always, lookup the error codes to get help in resolving compilation errors.

Weird MSC 8.0 error: "The value of ESP was not properly saved across a function call..."

We recently attempted to break apart some of our Visual Studio projects into libraries, and everything seemed to compile and build fine in a test project with one of the library projects as a dependency. However, attempting to run the application gave us the following nasty run-time error message:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function pointer declared with a different calling convention.
We have never even specified calling conventions (__cdecl etc.) for our functions, leaving all the compiler switches on the default. I checked and the project settings are consistent for calling convention across the library and test projects.
Update: One of our devs changed the "Basic Runtime Checks" project setting from "Both (/RTC1, equiv. to /RTCsu)" to "Default" and the run-time vanished, leaving the program running apparently correctly. I do not trust this at all. Was this a proper solution, or a dangerous hack?
This debug error means that the stack pointer register is not returned to its original value after the function call, i.e. that the number of pushes before the function call were not followed by the equal number of pops after the call.
There are 2 reasons for this that I know (both with dynamically loaded libraries). #1 is what VC++ is describing in the error message, but I don't think this is the most often cause of the error (see #2).
1) Mismatched calling conventions:
The caller and the callee do not have a proper agreement on who is going to do what. For example, if you're calling a DLL function that is _stdcall, but you for some reason have it declared as a _cdecl (default in VC++) in your call. This would happen a lot if you're using different languages in different modules etc.
You would have to inspect the declaration of the offending function, and make sure it is not declared twice, and differently.
2) Mismatched types:
The caller and the callee are not compiled with the same types. For example, a common header defines the types in the API and has recently changed, and one module was recompiled, but the other was not--i.e. some types may have a different size in the caller and in the callee.
In that case, the caller pushes the arguments of one size, but the callee (if you're using _stdcall where the callee cleans the stack) pops the different size. The ESP is not, thus, returned to the correct value.
(Of course, these arguments, and others below them, would seem garbled in the called function, but sometimes you can survive that without a visible crash.)
If you have access to all the code, simply recompile it.
I read this in other forum
I was having the same problem, but I just FIXED it. I was getting the same error from the following code:
HMODULE hPowerFunctions = LoadLibrary("Powrprof.dll");
typedef bool (*tSetSuspendStateSig)(BOOL, BOOL, BOOL);
tSetSuspendState SetSuspendState = (tSuspendStateSig)GetProcAddress(hPowerfunctions, "SetSuspendState");
result = SetSuspendState(false, false, false); <---- This line was where the error popped up.
After some investigation, I changed one of the lines to:
typedef bool (WINAPI*tSetSuspendStateSig)(BOOL, BOOL, BOOL);
which solved the problem. If you take a look in the header file where SetSuspendState is found (powrprof.h, part of the SDK), you will see the function prototype is defined as:
BOOLEAN WINAPI SetSuspendState(BOOLEAN, BOOLEAN, BOOLEAN);
So you guys are having a similar problem. When you are calling a given function from a .dll, its signature is probably off. (In my case it was the missing WINAPI keyword).
Hope that helps any future people! :-)
Cheers.
Silencing the check is not the right solution. You have to figure out what is messed up with your calling conventions.
There are quite a few ways to change the calling convetion of a function without explicitly specifying it. extern "C" will do it, STDMETHODIMP/IFACEMETHODIMP will also do it, other macros might do it as well.
I believe if run your program under WinDBG (http://www.microsoft.com/whdc/devtools/debugging/default.mspx), the runtime should break at the point where you hit that problem. You can look at the call stack and figure out which function has the problem and then look at its definition and the declaration that the caller uses.
I saw this error when the code tried to call a function on an object that was not of the expected type.
So, class hierarchy: Parent with children: Child1 and Child2
Child1* pMyChild = 0;
...
pMyChild = pSomeClass->GetTheObj();// This call actually returned a Child2 object
pMyChild->SomeFunction(); // "...value of ESP..." error occurs here
I was getting similar error for AutoIt APIs which i was calling from VC++ program.
typedef long (*AU3_RunFn)(LPCWSTR, LPCWSTR);
However, when I changed the declaration which includes WINAPI, as suggested earlier in the thread, problem vanished.
Code without any error looks like:
typedef long (WINAPI *AU3_RunFn)(LPCWSTR, LPCWSTR);
AU3_RunFn _AU3_RunFn;
HINSTANCE hInstLibrary = LoadLibrary("AutoItX3.dll");
if (hInstLibrary)
{
_AU3_RunFn = (AU3_RunFn)GetProcAddress(hInstLibrary, "AU3_WinActivate");
if (_AU3_RunFn)
_AU3_RunFn(L"Untitled - Notepad",L"");
FreeLibrary(hInstLibrary);
}
It's worth pointing out that this can also be a Visual Studio bug.
I got this issue on VS2017, Win10 x64. At first it made sense, since I was doing weird things casting this to a derived type and wrapping it in a lambda. However, I reverted the code to a previous commit and still got the error, even though it wasn't there before.
I tried restarting and then rebuilding the project, and then the error went away.
I was getting this error calling a function in a DLL which was compiled with a pre-2005 version of Visual C++ from a newer version of VC (2008).
The function had this signature:
LONG WINAPI myFunc( time_t, SYSTEMTIME*, BOOL* );
The problem was that time_t's size is 32 bits in pre-2005 version, but 64 bits since VS2005 (is defined as _time64_t). The call of the function expects a 32 bit variable but gets a 64 bit variable when called from VC >= 2005. As parameters of functions are passed via the stack when using WINAPI calling convention, this corrupts the stack and generates the above mentioned error message ("Run-Time Check Failure #0 ...").
To fix this, it is possible to
#define _USE_32BIT_TIME_T
before including the header file of the DLL or -- better -- change the signature of the function in the header file depending on the VS version (pre-2005 versions don't know _time32_t!):
#if _MSC_VER >= 1400
LONG WINAPI myFunc( _time32_t, SYSTEMTIME*, BOOL* );
#else
LONG WINAPI myFunc( time_t, SYSTEMTIME*, BOOL* );
#endif
Note that you need to use _time32_t instead of time_t in the calling program, of course.
I was having this exact same error after moving functions to a dll and dynamically loading the dll with LoadLibrary and GetProcAddress. I had declared extern "C" for the function in the dll because of the decoration. So that changed calling convention to __cdecl as well. I was declaring function pointers to be __stdcall in the loading code. Once I changed the function pointer from __stdcall to__cdecl in the loading code the runtime error went away.
Are you creating static libs or DLLs? If DLLs, how are the exports defined; how are the import libraries created?
Are the prototypes for the functions in the libs exactly the same as the function declarations where the functions are defined?
do you have any typedef'd function prototypes (eg int (*fn)(int a, int b) )
if you dom you might be have gotten the prototype wrong.
ESP is an error on the calling of a function (can you tell which one in the debugger?) that has a mismatch in the parameters - ie the stack has restored back to the state it started in when you called the function.
You can also get this if you're loading C++ functions that need to be declared extern C - C uses cdecl, C++ uses stdcall calling convention by default (IIRC). Put some extern C wrappers around the imported function prototypes and you may fix it.
If you can run it in the debugger, you'll see the function immediatey. If not, you can set DrWtsn32 to create a minidump that you can load into windbg to see the callstack at the time of the error (you'll need symbols or a mapfile to see the function names though).
Another case where esp can get messed up is with an inadvertent buffer overflow, usually through mistaken use of pointers to work past the boundary of an array. Say you have some C function that looks like
int a, b[2];
Writing to b[3] will probably change a, and anywhere past that is likely to hose the saved esp on the stack.
You would get this error if the function is invoked with a calling convention other than the one it is compiled to.
Visual Studio uses a default calling convention setting thats decalred in the project's options. Check if this value is the same in the orignal project settings and in the new libraries. An over ambitious dev could have set this to _stdcall/pascal in the original since it reduces the code size compared to the default cdecl. So the base process would be using this setting and the new libraries get the default cdecl which causes the problem
Since you have said that you do not use any special calling conventions this seems to be a good probability.
Also do a diff on the headers to see if the declarations / files that the process sees are the same ones that the libraries are compiled with .
ps : Making the warning go away is BAAAD. the underlying error still persists.
This happened to me when accessing a COM object (Visual Studio 2010). I passed the GUID for another interface A for in my call to QueryInterface, but then I cast the retrieved pointer as interface B. This resulted in making a function call to one with an entirely signature, which accounts for the stack (and ESP) being messed up.
Passing the GUID for interface B fixed the problem.
In my MFC C++ app I am experiencing the same problem as reported in Weird MSC 8.0 error: “The value of ESP was not properly saved across a function call…”. The posting has over 42K views and 16 answers/comments none of which blamed the compiler as the problem. At least in my case I can show that the VS2015 compiler is at fault.
My dev and test setup is the following: I have 3 PCs all of which run Win10 version 10.0.10586. All are compiling with VS2015, but here is the difference. Two of the VS2015s have Update 2 while the other has Update 3 applied. The PC with Update 3 works, but the other two with Update 2 fail with the same error as reported in the posting above. My MFC C++ app code is exactly the same on all three PCs.
Conclusion: at least in my case for my app the compiler version (Update 2) contained a bug that broke my code. My app makes heavy use of std::packaged_task so I expect the problem was in that fairly new compiler code.
ESP is the stack pointer. So according to the compiler, your stack pointer is getting messed up. It is hard to say how (or if) this could be happening without seeing some code.
What is the smallest code segment you can get to reproduce this?
If you're using any callback functions with the Windows API, they must be declared using CALLBACK and/or WINAPI. That will apply appropriate decorations to make the compiler generate code that cleans the stack correctly. For example, on Microsoft's compiler it adds __stdcall.
Windows has always used the __stdcall convention as it leads to (slightly) smaller code, with the cleanup happening in the called function rather than at every call site. It's not compatible with varargs functions, though (because only the caller knows how many arguments they pushed).
Here's a stripped down C++ program that produces that error. Compiled using (Microsoft Visual Studio 2003) produces the above mentioned error.
#include "stdafx.h"
char* blah(char *a){
char p[1];
strcat(p, a);
return (char*)p;
}
int main(){
std::cout << blah("a");
std::cin.get();
}
ERROR:
"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
I had this same problem here at work. I was updating some very old code that was calling a FARPROC function pointer. If you don't know, FARPROC's are function pointers with ZERO type safety. It's the C equivalent of a typdef'd function pointer, without the compiler type checking.
So for instance, say you have a function that takes 3 parameters. You point a FARPROC to it, and then call it with 4 parameters instead of 3. The extra parameter pushed extra garbage onto the stack, and when it pops off, ESP is now different than when it started. So I solved it by removing the extra parameter to the invocation of the FARPROC function call.
Not the best answer but I just recompiled my code from scratch (rebuild in VS) and then the problem went away.