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

前端之家收集整理的这篇文章主要介绍了当用作函数参数时,C“忘记”该变量是constexpr前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码,我厌倦了编译器无法看到作为函数的参数传递的变量是constexpr的事实,所以我必须使用arity 0函数而不是1参数函数. @H_404_2@我知道这不是编译器错误,但我想知道是否有成语可以解决这个问题.

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

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

@H_404_2@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;
    }
}
@H_404_2@这works in g++,但在clang我们得到一个问题,因为begin on an array isn’t properly constexpr with at least one library.或者可能g违反了标准,而clang没有.

猜你在找的C&C++相关文章