【问题标题】:std::array<T, N> with complex type and N=256/large [duplicate]std::array<T, N> 具有复杂类型和 N=256/large [重复]
【发布时间】:2019-03-26 22:41:52
【问题描述】:

我正在寻找一种方法来填充std::array&lt;T, N&gt;,其中 T 是一个非默认可构造的结构/类,而 N 在编译时确实是已知的,但它太大了,以至于你不想全部硬编码其中,例如N=256。构造函数(在我的例子中)接受一个参数,它基本上等于N,我想知道是否有一种方法可以在不进入复制粘贴地狱的情况下获得constexpr std::array&lt;T, 256&gt; values

使用unique_ptr 并在动态构造array&lt;unique_ptr&lt;T&gt;, 256&gt; 时创建所有元素会有一种解决方法。但这意味着我不能使用constexpr,也不是最好的解决方案。

我提供了我的问题的一般化(!)示例,我希望以这种方式工作。

#include <iostream>
#include <array>
using namespace std;

struct T { int value; }; // some struct/class with non-default ctor

// a workaround-attempt
template <const size_t N> struct TT : public T { constexpr TT(): T{N} {} };

template <const size_t N>
constexpr array<T, N> makeArray() {
    return {
            TT<1>{},
            TT<2>{},
            TT<3>{},
            TT<4>{},
            TT<5>{},
            // too bad I can't place this generically
    };
}

ostream& operator<<(ostream& os, T const& t) { return os << t.value; }

int main() {
    constexpr T a = TT<4>{};
    cout << a << "\n";

    constexpr array<T, 5> v = makeArray<5>();
    for (T const& t: v) cout << " " << t.value;
    cout << "\n";

    return 0;
}

这里应该很清楚,我目前正在硬编码 makeArray&lt;5&gt;() 方法,不使用 N,而是明确返回长度为 5 的数组(在我的代码中,这不是 5,而是 256):-) .

我目前正在使用 C++14 进行编码(没有机会过早升级到 C++17),并且我知道 C++20 中改进了 constexpr 松弛,但这里也不存在(不幸的是): -)

如何消除这种情况并使 C++14 中的代码看起来更干净?

【问题讨论】:

    标签: c++ arrays c++14 constexpr


    【解决方案1】:

    似乎适用于std::make_index_sequence/std::index_sequence

    template <std::size_t N, std::size_t ... Is>
    constexpr array<T, N> makeArray (std::index_sequence<Is...>)
     { return { { TT<Is+1>{} ... } }; }
    
    template <std::size_t N>
    constexpr array<T, N> makeArray ()
     { return makeArray<N>(std::make_index_sequence<N>{}); }
    

    【讨论】:

    • 相当肯定const&amp; 的索引序列比值更重。索引序列为空类型。
    • @GuillaumeRacicot - 真的吗?通过引用传递一个空结构体这么重?
    • 嗯,是的,也不是。在优化的版本号中。
    • 但它限制使用参数作为其他常量表达式的参数:godbolt.org/z/Fktcpq
    • @GuillaumeRacicot - 嗯......是的......考虑到一个体面的优化器和参数未被使用的事实,我认为没有真正的区别;但是您是否认为(使用的)参数(空类型)作为参考而不是副本更重要?无论如何:好点第二个:在这种特殊情况下不是问题,但在更复杂的情况下可能会破坏 const-expressness。我会努力记住的。
    猜你喜欢
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2021-05-05
    • 2015-08-04
    相关资源
    最近更新 更多