mscv-14 branch 2.0 compile problems: cannot cast lambda to std::function

46 views
Skip to first unread message

Sergio Garcia Murillo

unread,
Jan 13, 2017, 11:03:06 AM1/13/17
to firebreath-dev
Hello,

I was trying to compile latest code from branch 2.0 with Visual Studio 20015 Community Edition and I am getting the following kind of errors when trying to compile the test plugin:

C:\prog\FireBreath-2.0\src\FireWyrm\AlienWyrmling.cpp(125): error C2664: 'FB::Promise<FB::variant> FB::Promise<void>::thenPipe<FB::variant>(std::function<FB::variantPromise (void)>,std::function<FB::Promise<FB::variant> (std::exception_ptr)>) const': cannot convert argument 1 from 'FB::FireWyrm::AlienWyrmling::Invoke::<lambda_7d0129f19c4193e2d5fbf9013690dec1>' to 'std::function<FB::variantPromise (void)>'
1>  C:\prog\FireBreath-2.0\src\FireWyrm\AlienWyrmling.cpp(125): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

This happens for example on this kind of code:

variantPromise AlienWyrmling::Invoke(std::string methodName, const VariantList& args) {
    if (!m_valid) {
        throw FB::object_invalidated();
    }
    WyrmBrowserHostPtr host = getHost();
    auto spawnId = m_spawnId, objId = m_objId;
    return m_startup.thenPipe<FB::variant>([host, methodName, args, spawnId, objId]() -> FB::variantPromise {
        return host->DoCommand(FB::VariantList{ "Invoke", spawnId, objId, methodName, args });
    });
}

The problem seems to by that the thenPipe template method is expecting a std::function and msvc14 doesn't seem to allow casting the lambda function to the std::function

template <typename Uout>
Promise<Uout> thenPipe(std::function<Promise<Uout>()> cbSuccess, std::function<Promise<Uout>(std::exception_ptr)> cbFail = nullptr) const 

I am generating the msvc solution with 

prep2015x64.cmd examples  "-DWITH_SYSTEM_BOOST=1" "-DBOOST_ROOT=C:/usr/boost_1_63_0_x64" "-DBOOST_ADDITIONAL_VERSIONS=1.63.0" "-DBOOST_USE_STATIC_LIBS=ON" "-DBOOST_USE_STATIC_RUNTIME=ON"

And compiling in x64 debug using the latest precompiled boost library, but I think it should be possible to replicate it with any other version.


Any idea on how is the best way of fixing this? Does the lambda to std::function casting work on other c++ compilers?

Best regards
Sergio





Sergio Garcia Murillo

unread,
Jan 13, 2017, 3:00:57 PM1/13/17
to firebreath-dev
FWIW,

I have submitted a PR trying to address this issue:


It just fixes these compilation error, but project des not fully compile yet due to the binder issue that is also reported in another group message.

Hope it helps as a starting point to fix the compilation of 2.0 on VS 2015

Best regards
Sergio

Richard Bateman

unread,
Jan 13, 2017, 4:24:47 PM1/13/17
to FireBreath Dev Group
That's definitely one approach; I'm a bit concerned with this approach
though because it drastically reduces the compile-time checking and
may allow someone to pass in an invalid function.

I think I'll be able to look at this next week; there should be a way
to make it work correctly, we just need to figure out why vs2015
doesn't like the type.

Richard
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "firebreath-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to firebreath-de...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Sergio Garcia Murillo

unread,
Jan 13, 2017, 4:36:17 PM1/13/17
to firebre...@googlegroups.com
Thanxs Richard,

For what I have been searching there is no way to cast a lambda to an std::function, does this code works on other compilers not VS 2013?

Best regards
Sergio


> For more options, visit https://groups.google.com/d/optout.

--

---
You received this message because you are subscribed to a topic in the Google Groups "firebreath-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/firebreath-dev/rqPpI0FHXKM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to firebreath-dev+unsubscribe@googlegroups.com.

Richard Bateman

unread,
Jan 13, 2017, 4:37:50 PM1/13/17
to FireBreath Dev Group
I've only tested it so far on gcc, clang/xcode, and vs2013.

Richard
>> email to firebreath-de...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "firebreath-dev" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/firebreath-dev/rqPpI0FHXKM/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> firebreath-de...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "firebreath-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to firebreath-de...@googlegroups.com.

Richard Bateman

unread,
Jan 13, 2017, 4:42:17 PM1/13/17
to FireBreath Dev Group
Also while you're not going to cast a lambda to a std::function,
std::function was created to contain any callable type and to make
them abstract. you should absolutely be able to put a lambda in a
std::function as long as the types all match.

see http://www.drdobbs.com/cpp/efficient-use-of-lambda-expressions-and/232500059?pgno=2

http://stackoverflow.com/questions/7521805/implicitly-converting-lambda-to-boostfunction
(boost::function and std::function are nearly identical, std::function
having come from boost)

http://shaharmike.com/cpp/lambdas-and-functions/
- "std::function is a templated object that is used to store and call
any callable type, such as functions, objects, lambdas and the result
of std::bind."

Hope that helps,

Richard

Sergio Garcia Murillo

unread,
Jan 13, 2017, 4:42:54 PM1/13/17
to firebre...@googlegroups.com
"only" ;)

Weird then, according to the info I have been looking, there shouldn't
be possible to cast it, but it is working..

Best regards
Sergio

Richard Bateman

unread,
Jan 13, 2017, 4:46:01 PM1/13/17
to FireBreath Dev Group
Given that the whole point of std::function is to encapsulate
callables *of all kinds* that really confuses me. What info are you
reading that says that lambdas can't be put in a std::function?

Note that it isn't a cast... it's an implicit conversion. A cast
would imply that it was really the same type, which it is not.

Richard

On Fri, Jan 13, 2017 at 2:42 PM, Sergio Garcia Murillo

Sergio Garcia Murillo

unread,
Jan 13, 2017, 5:41:54 PM1/13/17
to firebre...@googlegroups.com
You are right, casting is not possible, but we don't want to cast it here.

Indeed the problem is trying encapsulate the lambda into an std:function
not matching the type of the parameters of the thenPipe.

If I try this on VS 2015 it is failing:

auto func = std::function<FB::variantPromise(void)>([host,
methodName, args, spawnId, objId]() -> FB::variantPromise {
return host->DoCommand(FB::VariantList{ "Invoke", spawnId,
objId, methodName, args });
});

With

1>C:\prog\FireBreath-2.0\src\FireWyrm\AlienWyrmling.cpp(126): error
C2440: '<function-style-cast>': cannot convert from
'FB::FireWyrm::AlienWyrmling::Invoke::<lambda_7d0129f19c4193e2d5fbf9013690dec1>'
to 'std::function<FB::variantPromise (void)>'
1> C:\prog\FireBreath-2.0\src\FireWyrm\AlienWyrmling.cpp(126): note: No
constructor could take the source type, or constructor overload
resolution was ambiguous

Best regards
Sergio

Richard Bateman

unread,
Jan 13, 2017, 6:22:41 PM1/13/17
to FireBreath Dev Group
I'll have to play with it a bit; the issue is that the overload
resolution is ambiguous, so it's quite possible that there is another
way to resolve the issue. For example, you could try:

auto lfunc = [host, methodName, args, spawnId, objId]() -> FB::variantPromise {
return host->DoCommand(FB::VariantList{ "Invoke", spawnId,
objId, methodName, args });
};
std::function<FB::variantPromise(void)> func(lfunc);

That was a totally off the cuff idea, but try breaking the lines down
smaller and smaller to figure out exactly where the problem is.

Richard

On Fri, Jan 13, 2017 at 3:41 PM, Sergio Garcia Murillo

Alexandre GOUAILLARD

unread,
Jan 14, 2017, 1:24:44 AM1/14/17
to firebre...@googlegroups.com
I resync'ed my GitHub fork with richard's and launched travis to check with Xcode.
results soon on:




>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>> --
>>>>>
>>>>> ---
>>>>> You received this message because you are subscribed to a topic in the
>>>>> Google Groups "firebreath-dev" group.
>>>>> To unsubscribe from this topic, visit
>>>>>
>>>>> https://groups.google.com/d/topic/firebreath-dev/rqPpI0FHXKM/unsubscribe.
>>>>> To unsubscribe from this group and all its topics, send an email to

>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>>
>>>>> --
>>>>>
>>>>> ---
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups
>>>>> "firebreath-dev" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an

>>>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>
>>> --
>>>
>>> --- You received this message because you are subscribed to the Google
>>> Groups "firebreath-dev" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an

>>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
>
> --- You received this message because you are subscribed to the Google
> Groups "firebreath-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an

> For more options, visit https://groups.google.com/d/optout.

--

---
You received this message because you are subscribed to the Google Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebreath-dev+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Alex. Gouaillard, PhD, PhD, MBA
------------------------------------------------------------------------------------
President - CoSMo Software Consulting, Singapore
------------------------------------------------------------------------------------

Sergio Garcia Murillo

unread,
Jan 14, 2017, 2:55:44 AM1/14/17
to firebre...@googlegroups.com
That fails with same error.

What I found interesting is that this works:

auto func = std::function<FB::Promise<void>()>([host, methodName, args,
spawnId, objId]() -> FB::variantPromise {
return host->DoCommand(FB::VariantList{ "Invoke", spawnId,
objId, methodName, args });
});

(Note Promise<void> as return type on std::function instead of
variantPromise).

Best regards
Sergio

Alexandre GOUAILLARD

unread,
Jan 14, 2017, 3:04:12 AM1/14/17
to firebre...@googlegroups.com
MSVC 2013 compiles: https://ci.appveyor.com/project/agouaillard/firebreath/build/1.0.10

I will push the app conveyor configuration file so you can all use it as a free safety net, later today (local time: 4pm)


For more options, visit https://groups.google.com/d/optout.
--

---
You received this message because you are subscribed to a topic in the
Google Groups "firebreath-dev" group.
To unsubscribe from this topic, visit

https://groups.google.com/d/topic/firebreath-dev/rqPpI0FHXKM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to

For more options, visit https://groups.google.com/d/optout.


--

---
You received this message because you are subscribed to the Google
Groups
"firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an

For more options, visit https://groups.google.com/d/optout.


--

--- You received this message because you are subscribed to the Google
Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an

For more options, visit https://groups.google.com/d/optout.


--

--- You received this message because you are subscribed to the Google
Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an

For more options, visit https://groups.google.com/d/optout.


--

--- You received this message because you are subscribed to the Google Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebreath-dev+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

Sergio Garcia Murillo

unread,
Jan 14, 2017, 11:47:04 AM1/14/17
to firebre...@googlegroups.com
I think that the "problem" is on variantPromise, the other compilation
problem is because it is not possible to convert from std::bind to
CallMethodFunctor and CallMethodFunctor is std::function <
variantPromise(const std::vector<variant>&) > ;

Best regards
Sergio

On 14/01/2017 0:22, Richard Bateman wrote:

Sergio Garcia Murillo

unread,
Jan 17, 2017, 4:25:51 AM1/17/17
to firebre...@googlegroups.com
I have created an standalone project to try to isolate the issue with promises and variants:

https://github.com/murillo128/fb-mvc14-issue

I am still digging into the issue but this compiles:

    auto good = std::function<FB::Promise<std::string>(void)>([]() -> FB::Promise<std::string> {
        FB::Promise<std::string> promise = "5";
        return promise;
    });

while this gives the fails:

    auto func = std::function<FB::Promise<FB::variant>(void)>([]() -> FB::Promise<FB::variant> {
        FB::Promise<FB::variant> promise = "5";
        return promise;
    });

'<function-style-cast>': cannot convert from 'main::<lambda_09135a3f243600ac2a62d73fbf2c95dc>' to 'std::function<FB::variantPromise (void)>'

No constructor could take the source type, or constructor overload resolution was ambiguous

Best regards
Sergio

To unsubscribe from this group and all its topics, send an email to firebreath-de...@googlegroups.com.

Sergio Garcia Murillo

unread,
Jan 17, 2017, 11:25:11 AM1/17/17
to firebreath-dev
I think I have found the problem, check the PR here:


I am not sure why it is being caused, but seems that the usage of

using CallMethodFunctor = std::function < variantPromise(const std::vector<variant>&) >;

on APITypes.h was causing variantPromise to be of incomplete type and causing all the other problems. Moving the CallMethodFunctor  and the other jsapi types to the JSAPI.h has fixed all the compilation issues for me.

Best regards
Sergio

On Friday, January 13, 2017 at 5:03:06 PM UTC+1, Sergio Garcia Murillo wrote:
Reply all
Reply to author
Forward
0 new messages