asio
asio copied to clipboard
Compilation issue when upgrading boost 1.71 to 1.80 ( VS 2015 )
My environment:
Visual Studio 2015 Update 2 (Version 14.0.25123.00) I have the following compilation error when calling the boost::asio::post:
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): error C2752: 'boost_asio_prefer_fn::call_traits<boost_asio_prefer_fn::impl,boost::asio::strand<boost::asio::io_context::executor_type>,void (const boost::asio::execution::detail::relationship::fork_t<0> &,boost::asio::execution::allocator_t<std::allocator<void>>),void,void,void,void,void,void,void>': more than one partial specialization matches the template argument list
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: could be 'boost_asio_prefer_fn::call_traits<Impl,T,void(P0,P1),enable_if<boost_asio_prefer_fn::call_traits<Impl,T,void(P0),void,void,void,void,void,void,void>::overload!=,void>::type,enable_if<boost_asio_prefer_fn::call_traits<Impl,call_traits<Impl,T,void(P0),void,void,void,void,void,void,void>::result_type,void(P1),void,void,void,void,void,void,void>::overload!=,void>::type,void,void,void,void,void>'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: or 'boost_asio_prefer_fn::call_traits<Impl,T,void(P0,P1,PN...),enable_if<boost_asio_prefer_fn::call_traits<Impl,T,void(P0),void,void,void,void,void,void,void>::overload!=,void>::type,enable_if<boost_asio_prefer_fn::call_traits<Impl,call_traits<Impl,T,void(P0),void,void,void,void,void,void,void>::result_type,void(P1,PN...),void,void,void,void,void,void,void>::overload!=,void>::type,void,void,void,void,void>'
c:\local\boost_1_80_0\boost\asio\use_future.hpp(141): note: see reference to class template instantiation 'boost::asio::use_future_t<std::allocator<void>>::std_allocator_void' being compiled
c:\local\boost_1_80_0\boost\asio\use_future.hpp(150): note: see reference to class template instantiation 'boost::asio::use_future_t<std::allocator<void>>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\relationship.hpp(595): note: see reference to class template instantiation 'boost::asio::execution::detail::relationship_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\outstanding_work.hpp(597): note: see reference to class template instantiation 'boost::asio::execution::detail::outstanding_work_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\occupancy.hpp(163): note: see reference to class template instantiation 'boost::asio::execution::detail::occupancy_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\mapping.hpp(764): note: see reference to class template instantiation 'boost::asio::execution::detail::mapping_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\context.hpp(170): note: see reference to class template instantiation 'boost::asio::execution::detail::context_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\bulk_guarantee.hpp(852): note: see reference to class template instantiation 'boost::asio::execution::detail::bulk_guarantee_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\blocking_adaptation.hpp(787): note: see reference to class template instantiation 'boost::asio::execution::detail::blocking_adaptation_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\execution\blocking.hpp(998): note: see reference to class template instantiation 'boost::asio::execution::detail::blocking_t<0>' being compiled
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): error C2672: 'operator __surrogate_func': no matching overloaded function found
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): error C2893: Failed to specialize function template 'enable_if<boost_asio_prefer_fn::call_traits<boost_asio_prefer_fn::impl,T,void(P0,P1,PN...),void,void,void,void,void,void,void>::overload==,call_traits<boost_asio_prefer_fn::impl,T,void(P0,P1,PN...),void,void,void,void,void,void,void>::result_type>::type boost_asio_prefer_fn::impl::operator ()(T &&,P0 &&,P1 &&,PN &&...) noexcept(<expr>) const'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: With the following template arguments:
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: 'T=boost::asio::strand<boost::asio::io_context::executor_type>'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: 'P0=const boost::asio::execution::detail::relationship::fork_t<0> &'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: 'P1=boost::asio::execution::allocator_t<std::allocator<void>>'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(59): note: 'PN={}'
c:\local\boost_1_80_0\boost\asio\impl\post.hpp(61): error C2672: 'operator __surrogate_func': no matching overloaded function found
That's the way we call post:
boost::asio::post( m_strand, boost::bind( &DeferedCallMechanism::Run,
this,
task,
nullptr,
threadId,
std::weak_ptr<std::promise>() ) );
I've been testing older versions of boost to identify when the problem started, so in version 1.71 the problem doesn't occur. So, the problem only occurred from version 1.73 -> 1.74 and so on.
I believe it is something in this change on standard executors, I've found it here, first item: https://www.boost.org/users/history/version_1_74_0.html
Another interesting point is that in visual studio 2015 update 3 the problem does not occur, only in update 2. As I can't update my version of the visual studio at the moment, do you know any way to solve this? a workaround would help.
Thanks in advance.
Please format your code properly, this very hard to read.
What C++ standard are you compiling for?
Does
boost::asio::post( m_strand, boost::bind( &DeferedCallMechanism::Run,
this,
task,
nullptr,
threadId,
std::weak_ptr<std::promise>() ) );
Work?
Please format your code properly, this very hard to read.
What C++ standard are you compiling for?
Does
boost::asio::post( m_strand, boost::bind( &DeferedCallMechanism::Run, this, task, nullptr, threadId, std::weak_ptr<std::promise>() ) );
Work?
It doesn't work, only with update 3 ( VS 2015 ).
C++ standard: C++14 toolset: msvc-14.0
What's the signature of DeferedCallMechanism::Run
?
What's the signature of
DeferedCallMechanism::Run
?
void Run( const Tasks::ITask::Ptr& task,
ILeaderWrapper* leaderWrapper,
const std::thread::id postingThreadId,
std::weak_ptr<std::promise<void>> leaderPromoted );
It does look like something is wrong with the bind
expression, can you try using a lambda instead?
It does look like something is wrong with the
bind
expression, can you try using a lambda instead?
Yes, I've tried it doesn't work, unfortunately. The error points me out to that implementation on boost\asio\impl\post.hpp
class initiate_post
{
public:
template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
typename enable_if<
execution::is_executor<
typename associated_executor<
typename decay<CompletionHandler>::type
>::type
>::value
>::type* = 0) const
{
typedef typename decay<CompletionHandler>::type handler_t;
typename associated_executor<handler_t>::type ex(
(get_associated_executor)(handler));
typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
execution::execute(
boost::asio::prefer(
boost::asio::require(ex, execution::blocking.never),
execution::relationship.fork,
execution::allocator(alloc)),
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler));
}
template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
typename enable_if<
!execution::is_executor<
typename associated_executor<
typename decay<CompletionHandler>::type
>::type
>::value
>::type* = 0) const
{
typedef typename decay<CompletionHandler>::type handler_t;
typename associated_executor<handler_t>::type ex(
(get_associated_executor)(handler));
typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
}
};
What does your lambda solution look like?
What does your lambda solution look like?
auto RunLambda = [ ]( const Tasks::ITask::Ptr& task,
ILeaderWrapper* leaderWrapper,
const std::thread::id postingThreadId,
std::weak_ptr<std::promise<void>> leaderPromoted )
{};
auto bind_handle = boost::bind<void>( RunLambda, task, nullptr, threadId, std::weak_ptr<std::promise<void>>( ) );
auto bind_exc_handle = boost::asio::bind_executor( m_strand, bind_handle );
boost::asio::post( bind_exc_handle );
Why are you capturing Tasks::ITask::Ptr
by reference, not by value?