微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当用作函数参数时,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没有.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐