[parameter] Preventing instantiation of lazy binding operator() until default is needed

This is a subset of my previous email, with a more specific and concrete example. The following code: #include <boost/parameter/name.hpp> #include <boost/parameter/binding.hpp> BOOST_PARAMETER_NAME(my_param) template <typename T> struct s {}; template <typename T> struct bogus { typedef typename s<T>::type result_type; template <typename U> struct result: public s<U> {}; result_type operator()() const {return 0;} }; template <typename ArgPack> void f(const ArgPack& ap) { const char* cs = ap[_my_param || bogus<const char*>()]; } int main(int, char**) { f(_my_param = "foo"); return 0; } does not work because result_type is invalid when the struct bogus is instantiated when creating the default value used in operator||(). If operator()() was a template, I think the compiler would delay instantiating it until it was called. Is there a way to force operator()() to be a template in Boost.Parameter, allowing its return type to only be instantiated when Boost.Parameter knows that the default will be used? This is a simplified example from a larger piece of code where the lazy default does not have a valid return type in some cases, and the parameter must be explicitly specified in those cases. Thank you. -- Jeremiah Willcock

AMDG Jeremiah Willcock wrote:
This is a subset of my previous email, with a more specific and concrete example. The following code:
#include <boost/parameter/name.hpp> #include <boost/parameter/binding.hpp>
BOOST_PARAMETER_NAME(my_param)
template <typename T> struct s {};
template <typename T> struct bogus { typedef typename s<T>::type result_type; template <typename U> struct result: public s<U> {}; result_type operator()() const {return 0;} };
template <typename ArgPack> void f(const ArgPack& ap) { const char* cs = ap[_my_param || bogus<const char*>()]; }
int main(int, char**) { f(_my_param = "foo"); return 0; }
does not work because result_type is invalid when the struct bogus is instantiated when creating the default value used in operator||(). If operator()() was a template, I think the compiler would delay instantiating it until it was called. Is there a way to force operator()() to be a template in Boost.Parameter, allowing its return type to only be instantiated when Boost.Parameter knows that the default will be used? This is a simplified example from a larger piece of code where the lazy default does not have a valid return type in some cases, and the parameter must be explicitly specified in those cases. Thank you.
In this case, there's nothing Boost.Parameter can do about it, since result type is instantiated when you construct bogus<const char*>(). There is no way to make operator() a template without having variadic templates or by making Boost.Parameter pass an argument to operator(). In Christ, Steven Watanabe

On Fri, 29 May 2009, Steven Watanabe wrote:
In this case, there's nothing Boost.Parameter can do about it, since result type is instantiated when you construct bogus<const char*>(). There is no way to make operator() a template without having variadic templates or by making Boost.Parameter pass an argument to operator().
I understand that. Is there some way to get a parameter passed to operator()? I think that would add an extra layer of template instantiation to allow the result type of operator() to be invalid. Could there be some special member type that Boost.Parameter looks for to decide whether to call def() or def(0)? That would keep compatibility while allowing more unusual cases like mine to work. -- Jeremiah Willcock
participants (2)
-
Jeremiah Willcock
-
Steven Watanabe