false-positive error using std::functional in vs2015 - c++

I have implemented some test functionals yesterday and everything compiled and worked fine without errors. Today i came back to my PC and my std::bind's are underlined red but compile without error. Seems like Intellisense and the compiler do not agree on the std::bind type. How can I fix this?
#include <functional>
class MyClass {
public:
int doE() {
return 0;
}
int doF() {
return 1;
}
};
void main()
{
MyClass obj;
std::function<int()> f = std::bind(&MyClass::doE, obj); // underlined red
std::cout << f();
}
The error message is as follows:
Error (active)
no suitable user-defined conversion from "std::_Binder<std::_Unforced, int (MyClass::*)(), MyClass &>" to "std::function<int ()>" exists
functionals
c:\functionals\functionals\thirdFunctionOnObject.h
I do have the same error type (Intellisense saying there is an error, but it compiles just fine) in more sophisticated code, where I used std::mem_fn().

Had the same problem with VS 2015 C++, I hate it. Microsoft drives me crazy.
For now I am using a nasty work around by moving the code to a static function. In your case it will be similar to the following:
class MyClass {
// other code
int doE () {
return 0;
}
static int statDoE(MyClass * myClass) {
return myClass->doE();
}
}

Related

std::thread(threadFunction, this); causes error in visual studio, but not visual studio code

So I have the following c++ class which stores a std::thread as a member variable, and starts a member function in that separate thread. However, this code only builds in visual studio code (using msys2 12.1.0 as a G++ compiler), and causes errors when I try to build it in visual studio code.
The line that causes the error seems to be: foo_thread = std::thread(threadFunction, this);
In visual studio code I get a red underline warning saying "no instance of constructor std::thread::thread" matches the argument list", however the code still compiles and runs fine.
In visual studio I get the same error, and a warning "C3867 'Foo::threadFunction': non-standard syntax; use '&' to create a pointer to member", and the code does not compile. When I try foo_thread = std::thread(&threadFunction, this); the error goes away, however when I try to build I get the error "&: illegal operation on bound member function expression. foo_thread = std::thread(&threadFunction, this); does still compile and run on visual studio code however.
How do I make this section work as desired and able to compile across c++ compilers/ides? It is also worth mentioning I don't seem to get these errors when the function that is handed to the newly spawned thread is not a member function, however I need it to be a member function for this program.
Code:
#include <thread>
#include <windows.h>
#include <iostream>
#define DllExport __declspec( dllexport )
typedef void (*funcPtr)(int num);
class Foo {
public:
// Value Constructor
Foo(int a, int b, funcPtr f) {
foo = a;
bar = b;
myFunc = f;
}
int getFoo() { return foo; };
int addBar(int a) { return private_method(a); };
void callMyFunc(int n) { myFunc(n); };
// Start Monitor
void StartThread();
// Stop Monitor
// IsMonitoring()
~Foo() {
if (foo_thread.joinable()) {
foo_thread.join();
}
};
private:
int private_method(int a) { return a + bar; };
int foo;
int bar;
std::thread foo_thread;
void threadFunction();
funcPtr myFunc;
std::atomic<bool> monitoring = ATOMIC_VAR_INIT(false);
};
void Foo::StartThread() {
foo_thread = std::thread(threadFunction, this);
}
void Foo::threadFunction() {
for (int i = 0; i < 10; i++) {
std::cout << "Hello:" << i << std::endl;
Sleep(500);
}
}
I figured it out, proper syntax to make this work is:
foo_thread = std::thread(&Foo::threadFunction, this);

C++ - Errors when trying to insert class into map

I have a map like so map<string, unique_ptr<Base>> variables and I am trying to insert data into the map variables.insert(make_pair("foo", new Int(10))) but I am getting to following errors:
error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::unique_ptr<Base>>::insert(std::pair<const char*, Int*>)’
variables.insert(make_pair("test", new Int(10)));
error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
template<typename _Pair, typename = typename
This is my code:
class Base {
public:
Base() {};
virtual ~Base() {};
};
class Int : public Base {
public:
Int(int i) {
this->i = i;
}
Int operator=(int i) {
this->i = i;
}
int i;
};
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", new Int(10)));
}
I think I need a fresh pair of eyes to look at this I'm not sure what this issue is, thanks!
Edit
I'm trying to make a heterogeneous map and there's a class for each data type. But I still get the same error no matter how many there are.
Note: This answer only applies to older versions of the main three compilers:
GCC: Applies to 5.3.1 or earlier. May apply to any version earlier than 6.1.0, but I haven't tested this.
Clang: Applies to 3.7.1 or earlier. May apply to any version earlier than 3.8.0, but I haven't tested this.
Visual Studio: Applies to 19.00.23506.0 or earlier. May apply to any version earlier than 19.00.23720.0, but I haven't tested this.
Conversely, if you have GCC 6.1.0 or later, Clang 3.8.0 or later, or Visual Studio 19.00.23720.0 or later, the original code should compile as is, without either of the modifications suggested in this answer.
[Thanks goes to AndyG for pointing out that it works with later versions of GCC & Clang.]
The problem appears to be that it isn't creating your unique_ptr from your raw pointer.
If you can use C++14, try std::make_unique().
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", make_unique<Int>(10)));
}
If you can't, then try something like this:
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));
}
Interestingly, I noticed a slight difference in how different compilers handle this. Using the following slightly modified version of your code as a test program:
#include <map>
#include <memory>
#include <iostream>
class Base {
public:
Base() {};
virtual ~Base() {};
};
class Int : public Base {
public:
Int(int i) {
this->i = i;
}
Int& operator=(int i) {
this->i = i;
// You forgot to return something.
return *this;
}
int i;
};
void set() {
using namespace std;
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", new Int(10)));
// C++14:
// variables.insert(make_pair("test", make_unique<Int>(10)));
// C++11:
// variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));
// Cheap hack for testing.
cout << static_cast<Int*>(variables["test"].get())->i << endl;
}
int main() {
set();
}
Most compilers* will fail to compile this, unless the initial line is commented out and either of the fixes is uncommented. However, the online MSVC compiler seemed to be able to compile it fine, without needing to uncomment either of the lines. Curiously, the version of MSVC available on Rextester failed to compile it without uncommenting one of the two lines.
* Tested online, with TutorialsPoint GCC, MSVC 2015 online, and Rextester Clang, GCC, and MSVC.

Template object as class parameter gives error before compiling

Here is the code:
#include <iostream>
using namespace std;
template<class OwnerType>
class Move {
public:
Move() {}
Move(OwnerType &_owner) {
owner = &_owner;
}
void GetPosition() {
cout << owner->x << endl;
}
OwnerType *owner;
};
class Entity {
public:
int x = 50;
Move<Entity> *move;
};
int main() {
Entity en;
en.x = 77;
en.move = new Move<Entity>(en); // sign '=' is underlined by VS
en.move->GetPosition();
return 0;
}
Error it gives :
a value of type "Move<Entity> *" cannot be assigned to an entity of type "Move<Entity> *"
The program is compiling, working as expected and gives expected values, however error is still here.
It's probably something to do with templates and compiling time and stuff but I don't have enough knowledge to know what this error actually represents.
Also don't worry about leaks since this was just me testing, error is what I don't understand.
Thanks in advance.
Intellisense is known for displaying invalid errors (see for example Visual Studio 2015: Intellisense errors but solution compiles), trust the compiler and linker, as suggested in comments.
However, this error is quite annoying, try closing the solution, delete the .suo file (it's hidden), and open in again. More info on what a .suo file is given here Solution User Options (.Suo) File
Side note, in your code example main is missing ().
so it is not Error.
it is Intellisense :
see:
Error 'a value of type "X *" cannot be assigned to an entity of type "X *"' when using typedef struct
Visual Studio 2015: Intellisense errors but solution compiles
old:
your main needs ():
this works for me:
#include<iostream>
using namespace std;
template<class T> class Move {
public:
Move() {}
Move(T &_owner) {
owner = &_owner;
}
void GetPosition() {
cout << owner->x << endl;
}
T *owner;
};
class Entity {
public:
int x = 50;
Move<Entity> *move;
};
int main(){
Entity en;
en.x = 77;
en.move = new Move<Entity>(en); // sign '=' is underlined by VS
en.move->GetPosition();
return 0;
}
output:
77

Problem replacing boost::bind with std::tr1::bind

I have the following code which compiles and runs fine under Visual Studio 2008 SP1.
#include <functional>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
class NoncopyableObject : public boost::noncopyable
{
public:
NoncopyableObject(int x) : x_(x) {}
int getValue() const {return x_;}
private:
int x_;
};
template<class F>
class MenuItemDispatcher
{
public:
MenuItemDispatcher(F f) : f_(f) { }
void operator ()(NoncopyableObject& w) const
{
// Invoke the functor
f_(w);
}
private:
typedef boost::function1<void,NoncopyableObject&> FUNC;
FUNC f_;
};
void MenuItem()
{
std::cout << "in MenuItem()\n";
}
template<class F>
MenuItemDispatcher<F> MakeMenuItemDispatcher(F f)
{
return MenuItemDispatcher<F>(f);
}
int main()
{
NoncopyableObject obj(7);
MakeMenuItemDispatcher(boost::bind(&MenuItem))(obj);
}
If I change the boost::bind to std::tr1::bind in main(), I get an error:
error C2248: 'boost::noncopyable_::noncopyable::noncopyable' : cannot access private member declared in class 'boost::noncopyable_::noncopyable'.
This diagnostic occurred in the compiler generated function 'NoncopyableObject::NoncopyableObject(const NoncopyableObject &)'
So it's trying to generate a copy constructor for NoncopyableObject. Anyone know why this might be so please? MenuItemDispatcher's call operator takes a reference to a NoncopyableObject, so I am struggling to see what's going wrong.
This appears to be a difference in how bind is implemented in MS Visual Studio (including 2010) and GNU gcc (I tested 4.4.1 and 4.5.2, both of which work the way you expected)
Consider the following code, given your definitions
auto b = boost::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj); // OK in VS and GCC
replacing boost::bind with std::bind (I'm using 2010, the error message appears to be the same as in your 2008)
auto b = std::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj); // compile error in VS 2010 SP1, OK in GCC
b(std::reference_wrapper<NoncopyableObject>(obj)); // OK in both
So, what happens is that MS's bind() makes a copy of its argument even if the argument is not going to be used, while boost's and GCC's bind() does not bother with that argument at all.
I was able to get your example to compile and run (on 2010) by changing the FUNC typedef to
typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;

BOOST_FOREACH: What is the error on using this of a STL container?

Does anyone know why the following generates an error on VC9?
class Elem;
class ElemVec : public vector<Elem>
{
public:
void foo();
};
void ElemVec::foo()
{
BOOST_FOREACH(Elem& elem, *this)
{
// Do something with elem
}
return;
}
The error I get is:
error C2355: 'this' : can only be referenced inside non-static member functions
The only (hack) solution I have right now which compiles without error is:
void ElemVec::foo()
{
ElemVec* This = this;
BOOST_FOREACH(Elem& elem, *This)
{
// Do something with elem
}
return;
}
You shouldn't inherit from STL containers. These are not polymorphic classes and it's the reason BOOST_FORACH can't handle your derived class.
Try to use aggregation instead.
Which compiler/Boost version are you using? I can compile the following without any problem (VS2005/Boost 1.38):
#include <boost/foreach.hpp>
using namespace std;
struct xxx : std::vector<int>
{
void test()
{
BOOST_FOREACH(int x, *this)
{
}
}
};
int main(void) {
xxx x;
x.test();
return 0;
}
Search the Boost bugbase if you want more details.
I had never seen that error. I guess it comes from the implementation of BOOST_FOREACH macro.
May i ask why you're creating a class based on vector<...> and not having a vector member variable ?
EDIT
Following this thread, i found out that this actually is a visual studio bug. The solution you have found seems to be the simplest.
Hmm, all compiled succesfully on my msvc (2005) compiller.
Maybe you have some error, but fixed or avoided it when was created your example.