snakster / cpp.react

C++React: A reactive programming library for C++11.
http://snakster.github.io/cpp.react/
Boost Software License 1.0
1.02k stars 128 forks source link

MakeSignal compilation error with Visual Studio 2017 using compiler flag /std:c++17 or /std:c++latest #24

Open scottmcnab opened 6 years ago

scottmcnab commented 6 years ago

cpp.react fails to compile on Visual Studio 2017 15.5.7 when attempting to use the C++17 compiler. Specifically, any code that attempts to call MakeSignal() gives build errors.

For example, building a single file BasicAlgorithms.cpp (using ctrl-F7) gives this error when compiler flag /std::c++17 is enabled in the project properties (under C/C++ --> Language --> C++ Language Standard):

1>------ Build started: Project: Example_BasicAlgorithms, Configuration: Debug x64 ------ 1>BasicAlgorithms.cpp 1>c:\git\rtvis\3rdparty\intel_tbb\include\tbb\task_group.h(113): error C4996: 'std::uncaught_exception': warning STL4006: std::uncaught_exception() is deprecated in C++17. It is superseded by std::uncaught_exceptions(), plural. You can define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.12.25827\include\exception(17): note: see declaration of 'std::uncaught_exception' 1>c:\git\cpp.react\include\react\detail\graph\algorithmnodes.h(371): error C2668: 'react::impl::apply': ambiguous call to overloaded function 1>c:\git\cpp.react\include\react\common\util.h(47): note: could be 'void react::impl::apply<react::impl::SyncedIterateByRefNode<D,S,E,react::impl::AddIterateByRefRangeWrapper<E,S,F,int>,int>::Tick::,std::tuple<std::shared_ptr>&>(F &&,T)' 1> with 1> [ 1> D=example6::D, 1> S=std::vector<int,std::allocator>, 1> E=int, 1> TNode=react::impl::SignalNode<example6::D,int>, 1> F=react::impl::SyncedIterateByRefNode<example6::D,std::vector<int,std::allocator>,int,react::impl::AddIterateByRefRangeWrapper<int,std::vector<int,std::allocator>,F,int>,int>::Tick::, 1> T=std::tuple<std::shared_ptr<react::impl::SignalNode<example6::D,int>>> & 1> ] 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.12.25827\include\tuple(1043): note: or 'decltype(auto) std::apply<react::impl::SyncedIterateByRefNode<D,S,E,react::impl::AddIterateByRefRangeWrapper<E,S,F,int>,int>::Tick::,std::tuple<std::shared_ptr>&>(_Callable &&,_Tuple)' [found using argument-dependent lookup] 1> with 1> [ 1> D=example6::D, 1> S=std::vector<int,std::allocator>, 1> E=int, 1> TNode=react::impl::SignalNode<example6::D,int>, 1> _Callable=react::impl::SyncedIterateByRefNode<example6::D,std::vector<int,std::allocator>,int,react::impl::AddIterateByRefRangeWrapper<int,std::vector<int,std::allocator>,F,int>,int>::Tick::, 1> _Tuple=std::tuple<std::shared_ptr<react::impl::SignalNode<example6::D,int>>> & 1> ] 1>c:\git\cpp.react\include\react\detail\graph\algorithmnodes.h(355): note: while trying to match the argument list '(react::impl::SyncedIterateByRefNode<D,S,E,react::impl::AddIterateByRefRangeWrapper<E,S,F,int>,int>::Tick::, std::tuple<std::shared_ptr>)' 1> with 1> [ 1> D=example6::D, 1> S=std::vector<int,std::allocator>, 1> E=int 1> ] 1> and 1> [ 1> TNode=react::impl::SignalNode<example6::D,int> 1> ] 1>c:\git\cpp.react\include\react\detail\graph\algorithmnodes.h(355): note: while compiling class template member function 'void react::impl::SyncedIterateByRefNode<D,S,E,react::impl::AddIterateByRefRangeWrapper<E,S,F,int>,int>::Tick(void )' 1> with 1> [ 1> D=example6::D, 1> S=std::vector<int,std::allocator>, 1> E=int 1> ] 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.12.25827\include\type_traits(517): note: see reference to class template instantiation 'react::impl::SyncedIterateByRefNode<D,S,E,react::impl::AddIterateByRefRangeWrapper<E,S,F,int>,int>' being compiled 1> with 1> [ 1> D=example6::D, 1> S=std::vector<int,std::allocator>, 1> E=int 1> ] 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.12.25827\include\memory(1284): note: see reference to class template instantiation 'std::is_convertible<_Yty ,_Ty *>' being compiled 1> with 1> [ 1> _Yty=NodeT, 1> _Ty=react::impl::SignalNode<example6::D,std::vector<int,std::allocator>> 1> ] 1>c:\git\cpp.react\include\react\algorithm.h(145): note: see reference to class template instantiation 'std::_SP_pointer_compatible<NodeT,TNode>' being compiled 1> with 1> [ 1> TNode=react::impl::SignalNode<example6::D,std::vector<int,std::allocator>> 1> ] 1>c:\git\cpp.react\examples\src\basicalgorithms.cpp(285): note: see reference to function template instantiation 'react::Signal<example6::D,std::vector<E,std::allocator<_Ty>>> react::Iterate<D,E,std::vector<_Ty,std::allocator<_Ty>>,example6::Sensor::,S,std::vector<_Ty,std::allocator<_Ty>>>(const react::Events<D,E> &,V &&,const react::SignalPack<D,S> &,FIn &&)' being compiled 1> with 1> [ 1> E=int, 1> _Ty=int, 1> D=example6::D, 1> S=int, 1> V=std::vector<int,std::allocator>, 1> FIn=example6::Sensor:: 1> ] 1>Done building project "Example_BasicAlgorithms.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Note: this exact same file compiles cleanly when the compiler flag /std:c++14 is used instead:

1>------ Build started: Project: Example_BasicAlgorithms, Configuration: Debug x64 ------ 1>BasicAlgorithms.cpp ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Do you know how to avoid this "ambiguous call to overloaded function" compiler error in C++17 mode? Any pointers would be greatly appreciated. Thanks!

scottmcnab commented 6 years ago

Note this error occurs when using the legacy1 branch that mirrors the documentation online.

scottmcnab commented 6 years ago

OK I found the cause of the problem - the C++14 implementation of "Unpack tuple" (in Util.h) fails when built using the C++17 compiler. If this apply() method is removed and replaced with the std::apply() implementation in the C++17 standard, then the compile errors disappear.

In case anyone else encounters this compile error, I have attached a patch that replaces apply() with std::apply() (note: this patch will break compatibility with C++14 compilers):

CppReact-apply-patch.txt