
Peter Dimov wrote:
David Abrahams wrote:
Peter, I've been expecting for some time that you were going to put the placeholders in a sub-namespace of boost, if only to avoid the ODR violations it is currently causing. No?
Correct me if I'm wrong, but the ODR violations are caused by the use of an unnamed namespace;
True.
this is not related to whether the placeholders are in a subnamespace of boost.
True again. That's a separate issue; anything we put outside boost is subject to unresolvable conflicts. <unnamed>:: is especially vulnerable.
It seems to me that Lambda's placeholders should be susceptible to the same sort of ODR violations.
I don't know what lambda does. I know mpl doesn't do that.
(I know that I asked you for an ODR/_1 example once and you provided it, but I don't remember what it was and can't find it at the moment. Sorry.)
int x(int); template <class T> void f() { boost::bind(x, _1); } Now all you need is for two translation units to instantiate f<X> for some X, the same in each TU.
The fact that I have to write mpl::_1 just to avoid colliding with <unnamed>::_1 is disconcerting at best. If another library came along and did what boost/bind/placeholders.hpp does, it would cause a clash.
First mover advantage, you know. (Kidding.)
My suggestion, assuming you care about backwards compatibility, is:
boost/bind/placeholders.hpp
declares placeholders in namespace boost::bind::placeholders.
But does not _define_ them?
You could define them as constants. Maybe enums would work: enum _1t { _1 }; enum _2t { _2 }; ??
(I had boost::placeholders in mind for a namespace, consistent with std::tr1::placeholders; when you use 'boost' as a substitute for 'std::tr1', boost::bind::placeholders won't work.)
Okay, as long as you cooperate with phoenix and lambda, as far as I'm concerned.
boost/bind/bind.hpp
has the current contents of boost/bind.hpp, except that placeholders are not declared in the <unnamed>::
boost/bind.hpp
#include <boost/bind/bind.hpp> #include <boost/bind/placeholders.hpp> namespace { using namespace boost::bind::placeholders; }
Hm. What is the difference between this directive and the simple
using namespace boost::bind::placeholders;
? I can't think of any.
Honestly, I'm not sure there is any.
This, of course, will still require you to use mpl::_1.
Yes, I expect that. Anyone conscientious will have to use qualification or local using directives to access placeholders.
I assume that you intend to fix all your includes to belong to... err, point to the using-directive-less version?
You bet. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com