constexpr矢量push_back或如何constexpr所有的东西

问题描述 投票:1回答:1

来自C ++ Now 2017的Jason Turner和Ben Deane有一个很好的演讲,名为constexpr All the things,它也提供了constexpr矢量实现。出于教育目的,我自己也在考虑这个想法。我的constexpr向量是纯粹的,因为推回它会返回一个带有附加元素的新向量。

在演讲中,我看到了一个或多或少跟随的qazxsw poi实现:

push_back

他们按价值采取元素并移动它,但我不认为这是我的问题的根源。我想知道的是,这个函数如何在constexpr上下文中使用?这不是const成员函数,它修改状态。我认为有可能做类似的事情

constexpr void push_back(T const& e) {
    if(size_ >= Size)
       throw std::range_error("can't use more than Size");
    else {
        storage_[size_++] = e;
    }
} 

如果这是不可能的,我们如何在constexpr上下文中使用这个东西并使用这个向量实现任务的目标,即编译时JSON解析?

这是我的版本,这样你就可以看到我的新矢量返回版本和谈话中的版本。 (注意,省略了性能,完美转发等问题)

constexpr cv::vector<int> v1;
v1.push_back(42);

所以,这件事让我意识到可能有一些我不了解constexpr的东西。所以,重新回答这个问题;这样一个constexpr矢量如何在constexpr上下文中提供类似变异的#include <cstdint> #include <array> #include <type_traits> namespace cx { template <typename T, std::size_t Size = 10> struct vector { using iterator = typename std::array<T, Size>::iterator; using const_iterator = typename std::array<T, Size>::const_iterator; constexpr vector(std::initializer_list<T> const& l) { for(auto& t : l) { if(size_++ < Size) storage_[size_] = std::move(t); else break; } } constexpr vector(vector const& o, T const& t) { storage_ = o.storage_; size_ = o.size_; storage_[size_++] = t; } constexpr auto begin() const { return storage_.begin(); } constexpr auto end() const { return storage_.begin() + size_; } constexpr auto size() const { return size_; } constexpr void push_back(T const& e) { if(size_ >= Size) throw std::range_error("can't use more than Size"); else { storage_[size_++] = e; } } std::array<T, Size> storage_{}; std::size_t size_{}; }; } template <typename T> constexpr auto make_vector(std::initializer_list<T> const& l) { return cx::vector<int>{l}; } template <typename T> constexpr auto push_back(cx::vector<T> const& o, T const& t) { return cx::vector<int>{o, t}; } int main() { constexpr auto v1 = make_vector({1, 2, 3}); static_assert(v1.size() == 3); constexpr auto v2 = push_back(v1, 4); static_assert(v2.size() == 4); static_assert(std::is_same_v<decltype(v1), decltype(v2)>); // v1.push_back(4); fails on a constexpr context } ?似乎它现在不在constexpr环境中工作。如果constexpr上下文中的push_back不打算开头,那么如何将其称为constexpr向量并将其用于编译时JSON解析?

c++ constexpr
1个回答
4
投票

您对矢量的定义是正确的,但您无法修改push_back对象。它们非常稳定。相反,在constexpr函数中进行编译时计算(然后可以将其输出分配给constexpr对象)。

例如,我们可以编写一个函数constexpr,它生成一个从range0的数字向量。它使用n,我们可以将结果分配给push_back中的constexpr向量。

main
© www.soinside.com 2019 - 2024. All rights reserved.