如何使用折叠表达式创建一个包含N个浮点值的数组?

huangapple go评论130阅读模式
英文:

How to create an array of N floats values with fold expression?

问题

以下是翻译好的部分:

假设以下函数:

template<size_t N>
constexpr std::array<float, N> make_ones()
{
    std::array<float, N> ret{};
    for (size_t k = 0; k != N; ++k)
    {
        ret[k] = 1.0f;
    }
    return ret;
}

是否可以使用折叠表达式(fold expression)编写这个函数?问题是我没有一个可展开的参数包。

英文:

Suppose the following function

template&lt;size_t N&gt;
constexpr std::array&lt;float, N&gt; make_ones()
{
    std::array&lt;float, N&gt; ret{};
    for (size_t k = 0; k != N; ++k)
    {
        ret[k] = 1.0f;
    }
    return ret;
}

Is it possible to write that with a fold expression?
The problem is that I do not have a pack to expand.

答案1

得分: 4

不可用fold expression,但可以使用pack expansion和*index sequence*,在[tag:C++20]中,您可以这样做:

template <size_t N>
constexpr std::array<float, N> make_ones()
{
    return []<size_t... Is>(std::index_sequence<Is...>) {
        return std::array<float, sizeof...(Is)>{( static_cast<void>(Is), 1.0f)...};
    }(std::make_index_sequence<N>{});
}

在godbolt.org上查看在线演示

对于不支持C++20或更高版本的编译器,您可以这样做:

template <size_t... Is>
constexpr std::array<float, sizeof...(Is)> make_ones_impl(std::index_sequence<Is...>)
{
    return std::array<float, sizeof...(Is)>{(static_cast<void>(Is), 1.0f)...};
}

template<size_t N>
constexpr std::array<float, N> make_ones()
{
    return make_ones_impl(std::make_index_sequence<N>{});
}
英文:

>Is it possible to write that with a fold expression?

Not with fold expression but pack expansion as well as with index sequence, in [tag:C++20] you could do:

template &lt;size_t N&gt;
constexpr std::array&lt;float, N&gt; make_ones()
{
    return []&lt;size_t... Is&gt;(std::index_sequence&lt;Is...&gt;) {
        return std::array&lt;float, sizeof...(Is)&gt;{( static_cast&lt;void&gt;(Is), 1.0f)...};
    }(std::make_index_sequence&lt;N&gt;{});
}

See live demo in godbolt.org


For compilers that doesn't support C++20 or later, you might do

template &lt;size_t... Is&gt;
constexpr std::array&lt;float, sizeof...(Is)&gt; make_ones_impl(std::index_sequence&lt;Is...&gt;)
{
    return std::array&lt;float, sizeof...(Is)&gt;{(static_cast&lt;void&gt;(Is), 1.0f)...};
}

template&lt;size_t N&gt;
constexpr std::array&lt;float, N&gt; make_ones()
{
    return make_ones_impl(std::make_index_sequence&lt;N&gt;{});
}

huangapple
  • 本文由 发表于 2023年8月5日 02:48:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838486.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定