$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Olaf Krzikalla (krzikalla_at_[hidden])
Date: 2008-06-02 08:15:39
Steven Watanabe wrote:
> Boost.Function doesn't provide such a utility. I can't see a way to
> get this information out of boost::bind using the public interface, either.
> visit_each skips placeholders.
IMHO it should be a feature of boost::function.
> If there is a way you would need
> something like this
>
> #include <boost/function.hpp>
> #include <boost/bind.hpp>
>
> struct bar {};
>
> class tSlot {
> public:
> template<class T>
> tSlot(const T& t) : uses_placeholder1(false),
> uses_placeholder2(false), f(t) {
> // do some magic to find which arguments are used.
> }
But what is the magic here?
An approach could be the introduction of a class function_invoker
leaving boost::function untouched:
----
struct function_invoker
{
template<class T>
function_invoker(function<T>& f); // throws, if f.empty();
// true, if a placeholder is used by f (should the index i
// be zero-based?):
bool uses_placeholder(int i) const;
// binds arg to a placeholder
template<class T>
void bind_placeholder(int i, T& arg);
template<class T>
void bind_placeholder(int i, const T& arg);
// throws, if a placeholder used by f is not bound to an argument:
fn_result call();
};
----
I'm aware that the implementation won't be that easy, esp. the static
computing of the type of fn_result could become difficult.
However it would solve my problem without bloating boost::function:
void foo(const tSlot& s)
{
function_invoker i(s);
s.bind_placeholder(1, 1);
bar b;
if (i.uses_placeholder(2)) // index is one-based)
{
expensive_calculation(b);
s.bind_placeholder(2, b);
}
s.call();
}
I'm wondering if Douglas Gregor is lurking and what his opinion is.
Best regards
Olaf Krzikalla