Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a constexpr function during pack expansion?

I want to do the following:

// have a constexpr function
template<class T>
constexpr T square( T const i )
{
    return i * i;
}

// transform a std::integer_sequence<> by calling the constexpr function on every integer
template<class Fn, class T, T... values>
static constexpr auto make_type( Fn fn, std::integer_sequence<T, values...> )
{
    return std::integer_sequence<T, fn( values )...>{};
}

// so that I can use it like so
using type = decltype( make_type( square, std::integer_sequence<int, 1, 2, 3>{} ) );

However, I get the following error:

...\main.cpp|19|error: 'fn' is not a constant expression|

like image 631
user2296177 Avatar asked Jul 01 '16 14:07

user2296177


1 Answers

fn is not usable in a constant expression - it's a bog-standard block-scope variable. You have to pass the functor as a type.

template <typename Fn, typename T, T... values>
static constexpr std::integer_sequence<T, Fn{}(values)...>
make_type(std::integer_sequence<T, values...>) {return {};}

And rewrite your function as

struct Square {
    template <typename T> constexpr T operator()(T const& t)
    {return t*t;}
};
like image 124
Columbo Avatar answered Sep 18 '22 05:09

Columbo