0
votes

Consider a c++ template function specialization :

namespace test {

   template < const int L, typename InputIt >
   typename std::iterator_traits<InputIt>::value_type
   Sum_L( InputIt beg, InputIt end)
   {
      typedef typename std::iterator_traits<InputIt>::value_type real_t;

      for( int i=0 ; i<L; ++i)
        call_rearrange_sum( beg, end);

      real_t sum( 0 );
      for( ; beg != end; ++beg)
        sum += *beg;

      return sum;
    }

   template < const int L, typename Real >
   Real
   Sum_L( const std::size_t len, Real * x)
   {          
      for( int i=0 ; i<L; ++i)
        call_rearrange_sum( x, x+len);

      Real sum( 0 );
      for( std::size_t i=0; i< len; ++i)
        sum += x[i];

      return sum;
    }

    template < typename Real, typename Func >
    Real
    special_sum( std::size_t len, const Real * const x, const Real * y, Func f)
    {
      std::vector<Real> res( 2*len );

      for( std::size_t i=0; i<len; ++i) {
        Real tmp;
        res.push_back( call_operator( x[i], y[i], &tmp);
        res.push_back( tmp );
      }

      return f( res.begin(), res.end(), f);
    }
}

Now I want to use the above functions as :

double my_test( const std::size_t len, double * x, double * y)
{
  return test::special_sum( len, x,y, 
                            test::Sum_L< 4, typename std::vector<double>::iterator> );
}

The gcc 4.9.2 it is not able to find the correct template specialization function. The error is "no matching function for call to 'special_sum(std::size_t&, const double*&, const double*&, < unresolved overloaded function type > )'.

Ι know that it is difficult to resolve by the compiler. From whatever I tried, it is one of the two template function 'Sum_L' to get an extra dummy-template argument. Is there any other way?

Thanks.

1
I guess you need SFINAE, remove one of Sum_L overload resolution.Ron Tang

1 Answers

0
votes

There is no such thing as partial specializations of function templates, the only way to specialize a function template is to provide a full specialization. What you are doing is actually just function overloading.

The easiest way to correct an ambiguous overload is to simply rename one of them. If you want to keep the name Sum_L around for certain uses, you could also just wrap it with a new function to be used for passing, like so:

template < const int L, typename InputIt >
typename std::iterator_traits<InputIt>::value_type
Sum_Wrapper(InputIt beg, InputIt end)
{
    return Sum_L<L, InputIt>(beg, end);
}

And then this should work fine:

double my_test(const std::size_t len, double * x, double * y)
{
    return test::special_sum<double>(len, x, y,
        test::Sum_Wrapper< 4, typename std::vector<double>::iterator>);
}