On Fri, Dec 16, 2011 at 2:46 PM, Rhys Ulerich <rhys.ulerich@gmail.com> wrote:
'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 <boost/call_traits.hpp>
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