VS 2015 Error when using nested lambda - c++

Here is a toned down version of my use case which compiles fine on gcc 4.9.3 and clang 3.7 but fails on VS 2015 Update 2.
#include <functional>
#include <string>
#include<memory>
namespace A {
using handle = std::function<void(std::string)>;
void func(std::string, handle) {
}
}
class B : public std::enable_shared_from_this<B> {
public:
void func();
};
void B::func()
{
auto && cast = std::static_pointer_cast<B>(shared_from_this());
auto const another_variable = [cast]() -> void
{
A::func("hello", [&cast](std::string){ } );
};
}
int main() {
return 0;
}
Here are the errors that I get
Error(s):
source_file.cpp(23): error C2440: '<function-style-cast>': cannot convert from 'const std::shared_ptr<_Ty>' to 'B::func::<lambda_4a58826445f3685613b078cf10fc9f7e>::()::<lambda_8290a9c207487c2dc2e26a5b929b4850>'
with
[
_Ty=B
]
source_file.cpp(23): note: No constructor could take the source type, or constructor overload resolution was ambiguous
source_file.cpp(23): error C2660: 'A::func': function does not take 1 arguments
Interestingly, it compiles fine on VS 2013 as well. Am I missing something very obvious?

Related

Weird error from Visual C++: No default constructor for promise type

Suppose I want to use coroutines with C++20 and restrict the promise type to accept only functions getting one argument of type int &. I write the following code:
#include <coroutine>
struct task {
struct promise_type {
promise_type(int &) {}
task get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
task my_task(int &) {
co_await std::suspend_never{};
}
int main() {
int x = 5;
my_task(x);
}
This compiles and works fine, both with GCC version 10+ and Visual Studio 2019 version 16.8+.
However, Visual Studio 2019 always complains that no default constructor exists for class "task::promise_type":
This error does not occur if I do not use a reference (e.g. int instead of int & as the argument type).
GCC does not show any warning or error, with and without the reference.
Am I doing something wrong?
Is this prohibited by the standard?
Or is it just a weird quirk of IntelliSense?
This seems to be a problem of IntelliSense and should work fine. To resolve the intellisense error, a constructor can be added just for IntelliSense:
#ifdef __INTELLISENSE__
promise_type();
#endif

std::function of a value templated method compiles with clang and g++ but not with msvc

The following code compiles with clang v5.0.0 and g++ v8.1.0 but fails with visual studio (2013 and 2017):
#include <string>
#include <functional>
#include <iostream>
template <const char* name>
std::string fct() {
return name;
}
const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;
int main(){
std::cout << fctptr() << std::endl;
}
The error is the following:
main.cpp(11): error C2440: 'initializing' : cannot convert from 'std::string (__cdecl *)(void)' to 'std::function<std::string (void)>'
1> No constructor could take the source type, or constructor overload resolution was ambiguous
I tried to replace the std::function with a typedef to a function pointer, as such:
typedef std::string(*Fctptr)();
Fctptr fctptr = fct<toto>;
However, I got the same error.
Is it a bug with msvc compiler, or is the above code not standard compliant.
FWIW, the following failed to compile using g++ 6.4.0 (g++ -std=c++11).
#include <string>
#include <functional>
#include <iostream>
template <const char* name>
std::string fct() {
return name;
}
const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;
int main(){
std::cout << fctptr() << std::endl;
}
Here's the error message:
socc.cc:11:43: error: the value of ‘toto’ is not usable in a constant expression
std::function<std::string()> fctptr = fct<toto>;
^~~~
socc.cc:10:12: note: ‘toto’ was not declared ‘constexpr’
const char toto[] = "toto";
Changing the definition of toto to
constexpr char toto[] = "toto";
resolved the problem.

false-positive error using std::functional in vs2015

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

C++ code with explicit casting, crashing Visual Studio compiler

I've installed Visual Studio 2013 to try some C++ code to test an idea of classes that mutate themselves into other classes and stuff like that (it's stupid but the idea came in a dream) and it is crashing visual studio's compiler, have no idea why.
Just by compiling it, a crash message with the title "Microsft C++ Optimizer deixou de funcionar" (stopped running in my language)
Code:
class F
{
public:
int f;
F(int f){ this->f = f; }
operator A(){ return A(f); }
operator P(){ return P(f); }
};
class A
{
public:
int a;
A(int a){ this->a = a; }
operator F(){ return F(a); }
operator P(){ return P(a); }
};
class P
{
public:
int p;
P(int p){ this->p = p; }
operator F(){ return F(p); }
operator A(){ return A(p); }
};
void stuff(F f)
{
printf("Val -> %d\n", f.f);
}
void main(int argc, char* argv[])
{
P p(3);
stuff((F)(A)(P)(F)(A)(P)(F)(A)p);
}
Tried to build it with gcc. No crashing, just no building either..
That is never going to work. It's way too late to even bother trying to unravel what you've tried to accomplish. Here's the error messages:
||=== 001-forumQuestion, Release ===|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|11|error: expected type-specifier before 'A'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|12|error: expected type-specifier before 'P'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|23|error: expected type-specifier before 'P'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|41|error: '::main' must return 'int'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp||In function 'int main(int, char**)':|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|44|error: no matching function for call to 'P::P(F)'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|44|note: candidates are:|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|31|note: P::P(int)|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|31|note: no known conversion for argument 1 from 'F' to 'int'|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|26|note: P::P(const P&)|
C:\Users\enhzflep\Documents\code\001-forumQuestion\main.cpp|26|note: no known conversion for argument 1 from 'F' to 'const P&'|
||=== Build finished: 5 errors, 0 warnings (0 minutes, 0 seconds) ===|

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;