|
Boost : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2003-09-18 02:43:27
Joel de Guzman wrote:
> Hi,
Hi Joel,
>
> Consider the following code:
>
> #include <boost/mpl/if.hpp>
> #include <boost/mpl/int.hpp>
>
> namespace X
> {
> template <int N>
> void
> if_(boost::mpl::int_<N>)
> {
> };
> }
>
> int
> main()
> {
> using namespace X;
> if_(boost::mpl::int_<1>());
> }
>
> g++ (3.2) complains:
>
> In function `int main()':
> template<class C, class T1, class T2> struct boost::mpl::if_' is not
> a function, conflict with `template<int N> void
> X::if_(boost::mpl::int_<N>)' in call to `if_'
>
> VC7.1 is OK.
>
> This is, AFAICT, an ADL (Koenig-lookup) problem. Which is correct,
> g++ or VC7.1?
> In any case, this is a real problem with libraries that, directly or
> indirectly, use MPL types.
It is! See also
http://www.mail-archive.com/boost@lists.boost.org/msg01780.html
> Is there a known solution (apart from asking the user to prefix if_
> with X::) ?
Yep, the solution outlined in the posting I cited above:
namespace boost { namespace mpl {
template< int n > struct int_ {};
namespace algo_ {
template< typename C, typename T1, typename T2 > struct if_ {};
}
using namespace algo_;
}}
namespace X
{
template <int N>
void
if_(boost::mpl::int_<N>)
{
};
}
int
main()
{
using namespace X;
if_(boost::mpl::int_<1>()); // OK!
}
Although, of course, the extreme case isn't possible to fix:
namespace X
{
template <int N>
void
int_(boost::mpl::int_<N>)
// ^^^^
{
};
}
int
main()
{
using namespace X;
int_(boost::mpl::int_<1>());
// ^^^^
}
Currently the workaround is applied only to the MPL algorithms which names
intersect with the standard ones. It probably won't hurt to apply it to
every metafunction that is not likely to be used as a value class.
In any case, 'if_' is now fixed in the main trunk.
HTH,
Aleksey
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk