[Proto] POD expression can't be used in std::vector

I have a expression who use BOOST_PROTO_EXTEND to be used as a POD type and I have a class inheriting from this expression to build a terminal class. When I build a std::vector of this terminal class using vector(size_t n) constructor I got the following error : /usr/include/c++/4.3.2/bits/stl_uninitialized.h:192: erreur: no matching function for call to ‘_Construct(const nt2::cmplx_expr<boost::proto::exprns_::expr<boost::proto::tag::address_of, boost::proto::argsns_::list1<nt2::cmplx_expr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<std::pair<float, float> >, 0l> >&>, 1l> >, const nt2::cmplx<float>&)’ And same for _Destruct() Seems & is used on the expression instead of the terminal class (a bit like the cout bug we found earlier). Is it a proto bug or a std bug ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou a écrit :
I have a expression who use BOOST_PROTO_EXTEND to be used as a POD type and I have a class inheriting from this expression to build a terminal class.
... Is it a proto bug or a std bug ?
OK seems I found the error myself. I was using bp::nary_expr< bp::_, bp::vararg<my_grammar> > as a rule in my_grammar, which obviously caught tag::address_of. Is it correct for matching any nary_expr *except* address_of : bp::nary_expr< bp::not_<pt::address_of>, bp::vararg<my_grammar> > or is there a better way if I want to prevent a subset of tag to be used ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Joel Falcou a écrit :
I have a expression who use BOOST_PROTO_EXTEND to be used as a POD type and I have a class inheriting from this expression to build a terminal class.
... Is it a proto bug or a std bug ?
OK seems I found the error myself. I was using
bp::nary_expr< bp::_, bp::vararg<my_grammar> >
as a rule in my_grammar, which obviously caught tag::address_of.
Is it correct for matching any nary_expr *except* address_of : bp::nary_expr< bp::not_<pt::address_of>, bp::vararg<my_grammar> >
or is there a better way if I want to prevent a subset of tag to be used ?
Right, as you've discovered, Proto overloads unary operator& by default, but you can turn it off in your domain's grammar. The grammar you suggested won't do it, though. Try this: proto::and_< proto::nary_expr<_, proto::vararg<my_grammar> > , proto::not_< proto::address_of<_> >
HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
Right, as you've discovered, Proto overloads unary operator& by default, but you can turn it off in your domain's grammar. The grammar you suggested won't do it, though. Try this:
proto::and_< proto::nary_expr<_, proto::vararg<my_grammar> > , proto::not_< proto::address_of<_> >
Works for GCC but ICC don't want to compile any operator (+,_, or w/e) ICC version for reference : version 10.1 for Linux -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
Right, as you've discovered, Proto overloads unary operator& by default, but you can turn it off in your domain's grammar. The grammar you suggested won't do it, though. Try this:
proto::and_< proto::nary_expr<_, proto::vararg<my_grammar> > , proto::not_< proto::address_of<_> >
Works for GCC but ICC don't want to compile any operator (+,_, or w/e) ICC version for reference : version 10.1 for Linux
Please post the code that reproduces the error. I'll try to get ICC set up on my Linux box. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
Please post the code that reproduces the error. I'll try to get ICC set up on my Linux box.
Here is a stripped down code that exhibits the bug (see attached file) Command-line invocation is inside the main.cpp Regards -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
Please post the code that reproduces the error. I'll try to get ICC set up on my Linux box.
Here is a stripped down code that exhibits the bug (see attached file)
Command-line invocation is inside the main.cpp
Looks like the intel compiler has a bug with ADL. You can work around it by changing the definition of cmplx to this: template<class T, typename Dummy = bp::is_proto_expr> struct cmplx ... Note the extra Dummy template parameter, which will cause ADL to find the operators defined in Proto's namespace. HTH, -- Eric Niebler BoostPro Computing www.boostpro.com

Eric Niebler a écrit :
Looks like the intel compiler has a bug with ADL. You can work around it by changing the definition of cmplx to this:
template<class T, typename Dummy = bp::is_proto_expr> struct cmplx ...
Note the extra Dummy template parameter, which will cause ADL to find the operators defined in Proto's namespace.
Perfect as usual :) This did the trick. I'll propagate this fix to all my terminal entity then. Should I report this to Intel bug system however ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
Looks like the intel compiler has a bug with ADL. You can work around it by changing the definition of cmplx to this:
template<class T, typename Dummy = bp::is_proto_expr> struct cmplx ...
Note the extra Dummy template parameter, which will cause ADL to find the operators defined in Proto's namespace.
Perfect as usual :) This did the trick. I'll propagate this fix to all my terminal entity then. Should I report this to Intel bug system however ?
You should, if you (or someone) can confirm it happens on Intel 11.0 also. Here is a simple repro: namespace N { struct S {}; template<class T, class U> void operator+(T const &, U const &) {} } template<class T> struct X {}; struct Y : X<N::S> {}; int main() { Y y; y+y; } The above code compiles with gcc but doesn't with Intel 10.1 -- Eric Niebler BoostPro Computing www.boostpro.com

Eric Niebler wrote:
namespace N { struct S {}; template<class T, class U> void operator+(T const &, U const &) {} }
template<class T> struct X {}; struct Y : X<N::S> {};
int main() { Y y; y+y; }
The above code compiles with gcc but doesn't with Intel 10.1
Hmm, comeau online rejects this code, too. (Not too surprising, I think Intel uses the comeau front end.) It's possible this is a gcc bug, not an Intel bug. When I have some time, I'll dive into the standard and see what it says about this case. -- Eric Niebler BoostPro Computing www.boostpro.com

Eric Niebler a écrit :
Hmm, comeau online rejects this code, too. (Not too surprising, I think Intel uses the comeau front end.) It's possible this is a gcc bug, not an Intel bug. When I have some time, I'll dive into the standard and see what it says about this case.
I'll d/l ICC 11 as soon as possible and see how it fares. Even if it's a gcc bug, can't we enforce the Dummy technique as *the* way to define proto extension ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
Hmm, comeau online rejects this code, too. (Not too surprising, I think Intel uses the comeau front end.) It's possible this is a gcc bug, not an Intel bug. When I have some time, I'll dive into the standard and see what it says about this case.
I'll d/l ICC 11 as soon as possible and see how it fares. Even if it's a gcc bug, can't we enforce the Dummy technique as *the* way to define proto extension ?
Well, the Dummy parameter is usually not needed, but you're right in that it never hurts to put it in. I'll make sure the documentation covers this case. -- Eric Niebler BoostPro Computing www.boostpro.com

You should, if you (or someone) can confirm it happens on Intel 11.0 also. Here is a simple repro:
namespace N { struct S {}; template<class T, class U> void operator+(T const &, U const &) {} }
template<class T> struct X {}; struct Y : X<N::S> {};
int main() { Y y; y+y; }
The above code compiles with gcc but doesn't with Intel 10.1
Intel 11.0 (Windows): t.cpp t.cpp(13): error: no operator "+" matches these operands operand types are: Y + Y y+y; ^ Regards Hartmut

Hartmut Kaiser wrote:
You should, if you (or someone) can confirm it happens on Intel 11.0 also. Here is a simple repro:
namespace N { struct S {}; template<class T, class U> void operator+(T const &, U const &) {} }
template<class T> struct X {}; struct Y : X<N::S> {};
int main() { Y y; y+y; }
The above code compiles with gcc but doesn't with Intel 10.1
Intel 11.0 (Windows):
t.cpp t.cpp(13): error: no operator "+" matches these operands operand types are: Y + Y y+y; ^
Thanks Hartmut. I checked the standard, and this appears to be correct behavior. That means that gcc's ADL is overeager. I've filed the bug here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38242 FWIW, MSVC also rejects this code. Thanks, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
Thanks Hartmut. I checked the standard, and this appears to be correct behavior. That means that gcc's ADL is overeager. I've filed the bug here:
FYI, ICC 11 Linux report same behavior Well, now another bugs of mine makes more sense. I had a similar overeager ADL using mpl types as template parameters. When I added a size function, compiler get confused between my size and mpl::size. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
participants (4)
-
Eric Niebler
-
Eric Niebler
-
Hartmut Kaiser
-
Joel Falcou