Closed Wentzell closed 8 years ago
are you compiling with C++11? Does it change if you add -std=c++11 to the compiler?
I did compile with
clang++-3.6 -std=c++11 -O1 test.cpp -o run
If I replace
class widget: public boost::multi_array<int, 1>
{};
with
class widget
{};
it compiles fine though. It seems to also be tied to the inheritance somehow..
ah, interesting. can you add the following to check if odeint correctly understands the C++11 mode:
#ifdef BOOST_NUMERIC_ODEINT_CXX11
std::cout << "C++ 11" << std::endl;
#endif
I tried, BOOST_NUMERIC_ODEINT_CXX11 is set to 1, so it seems to understand.
Hi,
this seems like an ADL (argument dependent lookup) issue, but I am not sure. Can you try to specify cref explictly from std:
auto widg_ref = std::cref( widg );
The ambiguity might be due to fact that widg is type from the boost namespace. The cref version from boost is therefore also considered as a valid expression or overload.
On 17.02.2016 13:36, Wentzell wrote:
I am using boost version 1.60.
The following snippet
include <boost/multi_array.hpp>
include <boost/numeric/odeint.hpp>
using namespace std;
class widget: public boost::multi_array<int, 1> {};
int main() { widget widg; auto widg_ref = cref(widg); }
gives the compiler error (clang++-3.6)
|test.cpp:12:20: error: call to 'cref' is ambiguous auto widg_ref = cref(widg); ^~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:449:5: note: candidate function [with _Tp = widget] cref(const _Tp& __t) noexcept ^ /usr/local/include/boost/core/ref.hpp:150:80: note: candidate function [with T = widget] template
BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( T const & t ) ^ | as apparently boost::cref is moved to the global scope? I want to only use std::cref though.
If I remove
include <boost/numeric/odeint.hpp>
it compiles fine.
— Reply to this email directly or view it on GitHub https://github.com/headmyshoulder/odeint-v2/issues/190.
I agree, the fact that it works when removing the derivation from boost::multi_array<int, 1>
strongly indicates it's ADL related. However, the problem also goes away when removing the odeint include, so it seems odeint somehow does include boost/ref.hpp
, although it's not supposed to when compiling in C++11 modes. Now I did a quick search on the odeint sources and ref.hpp
is only included from util/unwrap_reference.hpp
and there it is guarded by BOOST_NUMERIC_ODEINT_CXX11
. So maybe some other boost library that is used from odeint is pulling in boost/ref.hpp
- this is rather hard to find out here.
That easiest workaround should be to just explicitly use std::cref
. Another idea could be to not include odeint.hpp
, but only the part really needed in the end. Maybe then boost/ref.hpp
doesn't get pulled in.
On 17.02.2016 22:54, Mario Mulansky wrote:
I agree, the fact that it works when removing the derivation from |boost::multi_array<int, 1>| strongly indicates it's ADL related. However, the problem also goes away when removing the odeint include, so it seems odeint somehow does include |boost/ref.hpp|, although it's not supposed to when compiling in C++11 modes. Now I did a quick search on the odeint sources and |ref.hpp| is only included from |util/unwrap_reference.hpp| and there it is guarded by |BOOST_NUMERIC_ODEINT_CXX11|. So maybe some other boost library that is used from odeint is pulling in |boost/ref.hpp| - this is rather hard to find out here.
One can see the preprocessed source when compiling with -E . It seems that boost/ref ist included from some boost.fusion headers which are included in is_resizeable.
I don't know if this can somehow be avoided.
That easiest workaround should be to just explicitly use |std::cref|. Another idea could be to not include |odeint.hpp|, but only the part really needed in the end. Maybe then |boost/ref.hpp| doesn't get pulled in.
— Reply to this email directly or view it on GitHub https://github.com/headmyshoulder/odeint-v2/issues/190#issuecomment-185423988.
Well I don't think there is much we can do about that... The only chance I see is to go to Boost.Fusion with this example, but including boost.fusion instead of odeint, which should give the same error. Maybe they can do something about this problem...
@headmyshoulder Yes it compiles just fine if I resolve the ambiguity by specifying std::cref. ADL seems very likely indeed.
@mariomulansky
Indeed, the strange thing is that the ambiguity is tied to the inclusion of odeint.
The workaround you proposed is what I am using right now in my project.
I first thought I that I was missing some using directive hidden in my source files,
but then I was able to reproduce the problem with the minimal example above.
Would be nice to know where that boost/ref.hpp
inclusion is coming from.
I will have some a further look at the odeint sources myself when I find time.
Just read the last two posts, thanks! I will try posting the example there.
ok great - good luck! I will close this here then.
I am using boost version 1.60.
The following snippet
gives the compiler error (clang++-3.6)
as apparently boost::cref is moved to the global scope? I want to only use std::cref though.
If I remove
it compiles fine.