当用作函数参数时,C“忘记”该变量是constexpr

我有以下代码,我厌倦了编译器无法看到作为函数的参数传递的变量是constexpr的事实,所以我必须使用arity 0函数而不是1参数函数.

我知道这不是编译器错误,但我想知道是否有成语可以解决这个问题.

#include <array>
#include <iostream>

static constexpr std::array<int,5> arr{11,22,33,44,55};

template <typename C,typename P,typename Y>
static constexpr void copy_if(const C& rng,P p,Y yi3ld) {
    for (const auto& elem: rng) {
        if (p(elem)){
            yi3ld(elem);
        }
    }
}

// template<std::size_t N>
static constexpr auto get_evens(/* const std::array<int,N>& arr */) {
    constexpr auto is_even = [](const int i) constexpr {return i % 2 == 0;};
    constexpr int cnt = [/* &arr,*/&is_even]() constexpr {
        int cnt = 0;
        auto increment = [&cnt] (const auto&){cnt++;};
        copy_if(arr,is_even,increment);
        return cnt;
    }();
    std::array<int,cnt> result{};
    int idx = 0;
    copy_if(arr,[&result,&idx](const auto& val){ result[idx++] = val;});
    return result;
}

int main() {
    // constexpr std::array<int,55};
    for (const int i:get_evens(/* arr */)) {
        std::cout << i << " " << std::endl;
    }
}

如果我不想要的是什么:我想改变get_evens签名,使其在数组大小N上模板化,并且它需要一个类型为const std :: array< int,N>&的参数.

将arr更改为函数参数时的错误消息没有帮助:

prog.cc:25:21: note: initializer of ‘cnt’ is not a constant expression
prog.cc:19:19: note: declared here
constexpr int cnt = [&arr,&is_even]()constexpr {

解决方法

#include <array>
#include <iostream>

static constexpr std::array<int,typename T>
static constexpr void invoke_if(const C& rng,T target) {
    for (const auto& elem: rng) {
        if (p(elem)){
            target(elem);
        }
    }
}

constexpr bool is_even(int i) {
    return i % 2 == 0;
}

template<std::size_t N>
constexpr std::size_t count_evens(const std::array<int,N>& arr)
{
    std::size_t cnt = 0;
    invoke_if(arr,[&cnt](auto&&){++cnt;});
    return cnt;
}

template<std::size_t cnt,std::size_t N>
static constexpr auto get_evens(const std::array<int,N>& arr) {
    std::array<int,cnt> result{};
    int idx = 0;
    invoke_if(arr,55};
    for (const int i:get_evens<count_evens(arr)>(arr)) {
        std::cout << i << " " << std::endl;
    }
}

works in g++,但在clang我们得到一个问题,因为begin on an array isn’t properly constexpr with at least one library.或者可能g违反了标准,而clang没有.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...