How to implement folding with variadic templates

I have an almost working solution. However, it fails to compile some simple cases, and I can't decipher the error message.

My current solution:

#define AUTO_RETURN( EXPR ) -> decltype( EXPR ) \
{ return EXPR; }

template< typename BinaryFunc, typename First, typename Second >
auto foldl( BinaryFunc&& func, First&& first, Second&& second )
AUTO_RETURN( func( std::forward(first), std::forward(second) ) )

template
auto foldl( BinaryFunc&& func, First&& first, Second&& second, Rest&&... rest )
AUTO_RETURN(
   foldl(
      std::forward(func),
      func( std::forward(first), std::forward(second) ),
      std::forward(rest)... )
   )

This works as expected:

struct adder
{
   template< int LHS, int RHS >
   std::integral_constant
   operator()( std::integral_constant, std::integral_constant )
   {
      return {};
   }
};

auto result = foldl( adder(),
      std::integral_constant{},
      std::integral_constant{}
   );

assert( result.value == 42 );

However this fails to compile.

foldl( adder(),
      std::integral_constant{},
      std::integral_constant{},
      std::integral_constant{},
      std::integral_constant{},
   );

Oddly, if I remove all std::forward and rvalue refs from the code it works fine.

What am I doing wrong?
Is this a compiler bug?

12
задан deft_code 3 January 2012 в 20:06
поделиться