|
Boost : |
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-04-26 19:14:31
Hello,
TR1 section 3.6.4 says that placeholders should be default and copy
constructible. However, on gcc and borland boost::bind placeholders
are not copy constructible. I tried the following C++0x test.
#include <boost/tr1/functional.hpp>
#include <boost/concept_check.hpp>
int main()
{
boost::function_requires<
boost::DefaultConstructible<
typeof(std::tr1::placeholders::_1)
>
>();
boost::function_requires<
boost::CopyConstructible<
typeof(std::tr1::placeholders::_1)
>
>();
}
This works on gcc 4.1 with GNU's TR1 implementation, but when using
Boost.TR1 the second concept check fails to compile.
On gcc and borland the placeholders are defined as inline functions.
On all other compilers they are objects with internal linkage. From
reading the cvs logs for placeholders.hpp, inline function
placeholders are useful in order to avoid having data in headers.
(Also, apparently gcc may require placeholders to be inline functions
to workaround limitations in precompiled headers.) TR1 gets around the
data-in-headers issue by specifying that the placeholder declarations
in <functional> are extern. So, should Boost.Bind deviate from TR1
bind in terms of the linkage of placeholders or in terms of the set of
valid, TR1-compliant programs it can support based on concept
requirements?
I don't like the idea of requiring Boost.Bind users to link to a
library, so neither of these options are particularly attractive. As a
compromise, why not allow the user to choose whether placeholders are
internal objects or inline functions depending on their needs?
The attached patch does this by introducing a macro
BOOST_BIND_ENABLE_INLINE_PLACEHOLDERS. When it is defined placeholders
are not objects with internal linkage, and their types do not meet the
TR1 concept requirements; i.e. they're inline functions. When the
macro is not defined placeholders are objects with internal linkage,
and their types are both default and copy constructible. The macro is
undefined by default. If a user needs inline placeholders for
precompiled headers or whatever reason, they can make the trade off
and define the macro. The patch also includes user documentation.
The patch allows the code above to compile on gcc 4.1 with Boost.TR1,
and there are no errors detected when I run the bind test suite under
gcc 3.3/4.1 or msvc 7.1/8.0 with and without inline placeholders
enabled. Apply with 'patch -p0 < djw_bind_placeholders.patch' from the
boost root directory. I hope this is acceptable. Let me know if I'm
over looking something.
Thanks,
Daniel Walker
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk