【问题标题】:Arrays of Objects without standard constructor using Parameter Packs没有使用参数包的标准构造函数的对象数组
【发布时间】:2021-12-31 01:23:23
【问题描述】:

我想用没有标准构造函数的对象填充大小为 N 的 std::array。

std::array<non_std_con,N> myArray;

(具体来说,我是std::array&lt;kissfft&lt;float&gt;, 64&gt;

这会导致错误

错误:使用已删除的函数... 标准构造函数

设置

您可以使用初始化器列表填充数组:

std::array<non_std_con,N> myArray{non_std_con{init1,init2},non_std_con{init1,init2},...}

初始化列表需要 N 个对象。

您可以使用参数包构建数组:

template <class... Params>
auto constexpr build_array(Params... params)
{
    std::array<non_std_con, sizeof...(params)> myArray= {params...};
    return myArray;
}

问题

有没有办法反过来使用它并构建一个参数包 一个参数:

std::array<non_std_con,N> buildArray(inti1,init2);

这将构建一个 N non_std_con 数组,其中每个对象都被初始化为 {init1,init2}

感谢您的宝贵时间

【问题讨论】:

  • 那么,简单的auto my_array = std::array&lt;non_std_con,N&gt;{{init1, init2}}; 有用吗?
  • 不幸的是没有。这会导致错误:无法将“init1”从“int”转换为“non_std_con”
  • 等等,你的类型可以复制吗?
  • 您能简单地实际使用您在代码示例中使用的类型吗?这样就不用猜测了?
  • 嗯,应该是可复制构造的。我认为std::array&lt;kissfft&lt;float&gt;,64&gt; my_array{kissfft&lt;float&gt;(1&lt;&lt;15, false)} 也不起作用?

标签: c++ arrays c++20 initializer-list parameter-pack


【解决方案1】:

你可以写:

#include <array>
#include <utility>
#include <iostream>

namespace detail
{
    template <
        typename T,
        std::size_t ... Is
    >
    constexpr std::array<T, sizeof...(Is)> create_array(T value, std::index_sequence<Is...>)
    {
        // cast Is to void to remove the warning: unused value
        return {{(static_cast<void>(Is), value)...}};
    }
}

template<
    typename T,
    int N,
    typename... CtorAgrs
>
constexpr std::array<T, N> buildArray(CtorAgrs... args)
{
    using Array = std::array<T, N>;
    return detail::create_array<T>(T{args...}, std::make_index_sequence<N>());
}


struct Foo{
    int a, b;
    constexpr Foo(int a, int b) : a(a), b(b)
    {
    }
};

int main() {
    constexpr auto array = buildArray<Foo, 10>(1, 2);

    for(const auto& f : array){
        std::cout << f.a;
        std::cout << "\n";
    }
}

或者简单地使用 C++-20:

template<
    typename T,
    int N,
    typename... CtorAgrs
>
constexpr std::array<T, N> buildArray(CtorAgrs&&... args)
{
    auto doBuildArray = [&]<std::size_t ... Is>(std::index_sequence<Is...>)
    ->  std::array<T, N>
    {
        // cast Is to void to remove the warning: unused value
        return {{(static_cast<void>(Is), T{args...})...}};
    };

    return doBuildArray(std::make_index_sequence<N>());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2013-10-30
    相关资源
    最近更新 更多