[call_traits] Having trouble with call traits combined with type deduction

'Afternoon,
I have a quick question on call traits and template argument
deduction. I want to use call_traits' value_type and param_type to
deduce a signature like
double desired_result(double const& x);
given an argument of type double.
Is there any way to get type deduction working on a snippet like
lousy_attempt (below) to produce my desired_result?
#include

On Fri, Dec 16, 2011 at 2:46 PM, Rhys Ulerich
'Afternoon,
I have a quick question on call traits and template argument deduction. I want to use call_traits' value_type and param_type to deduce a signature like double desired_result(double const& x); given an argument of type double.
Is there any way to get type deduction working on a snippet like lousy_attempt (below) to produce my desired_result?
#include
template<typename Scalar> typename boost::call_traits<Scalar>::value_type lousy_attempt(typename boost::call_traits<Scalar>::param_type x) { return x; }
int main() { double y = 5;
// Works... lousy_attempt<double>(y);
// "No matching function call to lousy_attempt(double&)" lousy_attempt(y);
return 0; }
Thanks in advance, Rhys
What you're doing can't work, as the compiler cannot deduce a template parameter based on matching to a nested type. Consider an arbitrary metafunction X<T>, with any number of specializations; how could the compiler deduce the correct "T" to match double (or whatever type) to X<T>::type? The compiler has no way of going from the ::type you're trying to match back to T. If you really want this effect, you can use Boost.EnableIf: template< class T > typename boost::enable_if_c< boost::is_same< T const, typename boost::call_traits<T>::param_type >::value
::type f(T const x) { /*...*/ }
template< class T > typename boost::enable_if_c< boost::is_same< T const &, typename boost::call_traits<T>::param_type >::value
::type f(T const & x) { /*...*/ }
Or, you can explicitly provide the template parameter to your definition of lousy_attempt. Or pass an extra, dummy argument to your function that presents T in a deduced context. But I would generally recommend to just use T const &. - Jeff

Hi Jeffrey,
Is there any way to get type deduction working on a snippet like lousy_attempt (below) to produce my desired_result?
template<typename Scalar> typename boost::call_traits<Scalar>::value_type lousy_attempt(typename boost::call_traits<Scalar>::param_type x) { return x; }
int main() { double y = 5;
// Works... lousy_attempt<double>(y);
// "No matching function call to lousy_attempt(double&)" lousy_attempt(y);
return 0; }
What you're doing can't work, as the compiler cannot deduce a template parameter based on matching to a nested type.
Ah.
If you really want this effect, you can use Boost.EnableIf...
That snippet was a drastically simplified version of some large code. The enable_if mechanism makes sense but will be a painful burden.
But I would generally recommend to just use T const &.
I'll keep with your recommendation. Thank you for the excellent explanation, Rhys
participants (2)
-
Jeffrey Lee Hellrung, Jr.
-
Rhys Ulerich