在包扩展期间如何使用 constexpr 函数?
How can I use a constexpr function during pack expansion?
我想执行以下操作:
// 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>{} ) );
但是,我收到以下错误:
...\main.cpp|19|error: 'fn' is not a constant expression|
fn
在常量表达式中不可用 - 它是沼泽标准块作用域变量。您必须将仿函数作为类型传递。
template <typename Fn, typename T, T... values>
static constexpr std::integer_sequence<T, Fn{}(values)...>
make_type(std::integer_sequence<T, values...>) {return {};}
并将您的函数重写为
struct Square {
template <typename T> constexpr T operator()(T const& t)
{return t*t;}
};
除了 constexpr
不是函数指针类型的一部分之外,square
是一个模板,因此您不能通过通常的隐式衰减形成指向它的指针。
但无需更改 make_type
函数的签名即可实现此功能。将 Square
重写为函子:
struct Square {
template<class T>
constexpr T operator()( T const& i )
{
return i * i;
}
};
并这样称呼它:
using type = decltype( make_type( square{}, std::integer_sequence<int, 1, 2, 3>{} ) );
在 C++17 中,您将能够使用 constexpr
lambda:
constexpr auto square = [](auto const& i) { return i * i; };
using type = decltype( make_type( square, std::integer_sequence<int, 1, 2, 3>{} ) );
我想执行以下操作:
// 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>{} ) );
但是,我收到以下错误:
...\main.cpp|19|error: 'fn' is not a constant expression|
fn
在常量表达式中不可用 - 它是沼泽标准块作用域变量。您必须将仿函数作为类型传递。
template <typename Fn, typename T, T... values>
static constexpr std::integer_sequence<T, Fn{}(values)...>
make_type(std::integer_sequence<T, values...>) {return {};}
并将您的函数重写为
struct Square {
template <typename T> constexpr T operator()(T const& t)
{return t*t;}
};
除了 constexpr
不是函数指针类型的一部分之外,square
是一个模板,因此您不能通过通常的隐式衰减形成指向它的指针。
但无需更改 make_type
函数的签名即可实现此功能。将 Square
重写为函子:
struct Square {
template<class T>
constexpr T operator()( T const& i )
{
return i * i;
}
};
并这样称呼它:
using type = decltype( make_type( square{}, std::integer_sequence<int, 1, 2, 3>{} ) );
在 C++17 中,您将能够使用 constexpr
lambda:
constexpr auto square = [](auto const& i) { return i * i; };
using type = decltype( make_type( square, std::integer_sequence<int, 1, 2, 3>{} ) );