Here is a proof-of-concept of what I had in mind, any thoughts?

```
// <x3/support/utility/priority_tag.hpp>
namespace utility
{
	template <std::size_t I>
	struct priority_tag : priority_tag<I - 1> {};

	template <>
	struct priority_tag<0> {};
}

// <x3/core/detail/invoke_action.hpp>
namespace detail
{
	template <typename F, typename Context, typename Attribute,
		typename Enable = typename std::enable_if<
			is_callable<F(Context const&, Attribute&)>::value>::type>
	void invoke_action(utility::priority_tag<2> const&,
	    F& f, Context const& context, Attribute& attribute)
	{
		f(context, attribute);
    }

	template <typename F, typename Context, typename Attribute,
		typename Enable = typename std::enable_if<
			is_callable<F(Context const&)>::value>::type>
	void invoke_action(utility::priority_tag<1> const&,
	    F& f, Context const& context, Attribute& attribute)
	{
		f(attribute);
	} // this one should be split in mem-fn and non-mem-fn

	template <typename F, typename Context, typename Attribute,
		typename Enable = typename std::enable_if<
			is_callable<F()>::value>::type>
	void invoke_action(utility::priority_tag<0> const&,
	    F& f, Context const& context, Attribute& attribute)
	{
		f();
	}

	template <typename F, typename Context, typename Attribute>
	void invoke_action(F&& f, Context const& context, Attribute& attribute)
	{
		return invoke_action(utility::priority_tag<3>{},
		    f, context, attribute);
	}
}
```