On 6/6/15 8:45 PM, Lee Clagett wrote:
The problem are the immediate instantations of `typename get_promotion_policy<T>::type` which cause the static assert to be instantiated too. You need to delay instantating ::type in these objects until std::is_same needs to be evaluated. I don't know know of a way to do this with standard MPL (see https://abel.web.elte.hu/mpllibs/metamonad/lazy.html ), but one easy way with C++11 (if metaparse is not an option):
template class F, typename... A> struct lazy_eval { using type = typename F<typename A::type...>::type; };
// if both types are safe, the policies have to be the same! static_assert( boost::mpl::eval_if< boost::mpl::and_< is_safe<T>, is_safe<U> >, lazy_eval< std::is_same, get_promotion_policy<T>, get_promotion_policy<U> >, boost::mpl::identityboost::mpl::true_ >::type::value, "if both types are safe, the policies have to be the same!" );
which will work with any metafunction F that accepts 1 or more arguments. There might be some way to re-write what you are trying to avoid this, but I haven't put much thought into that.
Thanks for responding. I also believe that the problem is that is_same is getting invoked "too soon". It is for this reason I used eval_if which is intended to avoid instantiation of it's arguments but just return the type of the selected one. Clearly I've got something wrong. I tried your code exactly as you've written it but I get the same error. MPL has similar functionality in the metafunction "apply" - though I hadn't tried that. So I'm still stumped - but, again, thanks for taking the time to look at this. Robert Ramey