在诉讼中的constexpr
constexpr in for-Statement
c 17提供if constexpr
,其中:
条件的值必须是类型
bool
的上下文转换的常数表达。如果该值为true
,则丢弃语句 - false(如果存在(,则丢弃语句 - 真实
也有办法在for
统计中使用它吗?在编译时展开循环?我喜欢做这样的事情:
template <int T>
void foo() {
for constexpr (auto i = 0; i < T; ++i) cout << i << endl;
}
还有一种方法可以在陈述中使用它吗?在编译时展开循环?我喜欢做这样的事情
我不以一种简单的方式思考。
但是,如果您可以负担得起辅助功能,则使用std::integer_sequence
和未使用的C风格整数阵列的初始化,从C 14开始,您可以按照以下操作
#include <utility>
#include <iostream>
template <int ... Is>
void foo_helper (std::integer_sequence<int, Is...> const &)
{
using unused = int[];
(void)unused { 0, (std::cout << Is << std::endl, 0)... };
}
template <int T>
void foo ()
{ foo_helper(std::make_integer_sequence<int, T>{}); }
int main ()
{
foo<42>();
}
如果您可以使用C 17,则可以避免使用unused
数组,并且使用折叠,foo_helper()
可以简单地写入如下
template <int ... Is>
void foo_helper (std::integer_sequence<int, Is...> const &)
{ ((std::cout << Is << std::endl), ...); }
如果编译器已知循环限制,则编译器将揭开循环,如果发现它有益。并非所有循环展开都是有益的!而且,您不太可能做出比编译器更好的决定。
不需要constexpr for
(如您所说的(,因为constexpr if
正在启用功能 - 您可以放置代码,该代码将使程序在constexpr if
False Branch内部不构建,这不是纯粹的优化。
Constexpr for
将是纯粹的优化(至少如您所描述的那样,不计算0次执行的环路案例(,因此最好将" AS-IF"优化规则保留。
不是没有辅助代码。
#define RETURNS(...)
noexcept(noexcept(__VA_ARGS__))
-> decltype(__VA_ARGS__)
{ return __VA_ARGS__; }
template<std::size_t I>
using index_t = std::integral_constant<std::size_t, I>;
template<std::size_t...Is>
constexpr auto index_over( std::index_sequence<Is...> ) noexcept(true) {
return [](auto&& f)
RETURNS( decltype(f)(f)( index_t<Is>{}... ) );
}
template<std::size_t N>
constexpr auto index_upto( index_t<N> ={} ) noexcept(true) {
return index_over( std::make_index_sequence<N>{} );
}
template<class F>
constexpr auto foreacher( F&& f ) {
return [&f](auto&&...args) noexcept( noexcept(f(args))&&... ) {
((void)(f(args)),...);
};
}
那是我们的管道。
template<int T>
void foo() {
index_upto<T>()(
foreacher([](auto I){
std::cout << I << "n";
})
);
}
每个步骤上具有值的编译时循环。
,或者我们可以隐藏详细信息:
template<std::size_t start, std::size_t length, std::size_t step=1, class F>
constexpr void for_each( F&& f, index_t<start> ={}, index_t<length> ={}, index_t<step> ={} ) {
index_upto<length/step>()(
foreacher([&](auto I){
f( index_t<(I*step)+start>{} );
})
);
}
然后我们得到:
for_each<0, T>([](auto I) {
std::cout << I << "n";
});
或
for_each([](auto I) {
std::cout << I << "n";
}, index_t<0>{}, index_t<T>{});
使用用户定义的文字和模板变量可以进一步改善这一点:
template<std::size_t I>
constexpr index_t<I> index{};
template<char...cs>
constexpr auto operator""_idx() {
return index< parse_value(cs...) >;
}
其中parse_value
是constexpr
函数,该函数采用char...
的序列并产生其无符号整数表示。
相关文章:
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 如何在 constexpr 函数中实现回退运行时
- 在非 constexpr 函数中作为左值传递的变量上使用 'constexpr' 函数
- constexpr函数中的静态constexpr变量
- 如何将临时 C 数组传递到 constexpr 容器中
- 在 constexpr funnction 中调用basic_string函数
- 在 constexpr 函数中断言
- 将字符串存储在 constexpr 结构中
- 如何将用户定义的文字放在C++相同类型的 constexpr 类中?
- 在constexpr函数中插入许多模板
- constexpr 函数中的 for 循环无法使用 MSVC 19.23 进行编译
- 在 C++17 中修改 constexpr 函数中的全局变量
- 在 constexpr 功能中切换
- constexpr 类中的引用字段
- ADL 在 constexpr 函数中不起作用(仅限 clang)
- C++将静态多态类自添加到子类的 constexpr 列表中
- constexpr类中的C 常量指针
- 在诉讼中的constexpr
- 在ConstexPR函数中,断点被击中
- 如何在 constexpr 函数中强制编译错误,而不是让它衰减到非 constexpr 上下文中?