C++ 对于constexpr函数中的constexpr
我正在编写一个constexpr函数,需要使用一个constexpr函数。循环可以手动扩展,但我发现代码很难看,而且冗余 我怎样才能做一个“constexpr for” 我应该创建一个助手类吗?如果是这样的话,我该怎么写这样的东西:C++ 对于constexpr函数中的constexpr,c++,c++20,C++,C++20,我正在编写一个constexpr函数,需要使用一个constexpr函数。循环可以手动扩展,但我发现代码很难看,而且冗余 我怎样才能做一个“constexpr for” 我应该创建一个助手类吗?如果是这样的话,我该怎么写这样的东西: #define for_constexpr( TYPE, VAR, START, CONDITION, END_OP, BODY ) \ for_constexpr_helper< \ TYPE, START, // TYPE STAR
#define for_constexpr( TYPE, VAR, START, CONDITION, END_OP, BODY ) \
for_constexpr_helper< \
TYPE, START, // TYPE START = 0; \
[ ]( TYPE VAR ) constexpr { return CONDITION; }, \
[ ] constexpr { END_OP; }, \
[ & ]( TYPE VAR ) constexpr { BODY; } >( )
这不是constexpr。丑陋的例子:
auto ret = 0;
ret += 1;
ret += 2;
ret += 3;
return ret; // works
我不会用宏来做这件事。如果您可以通过“传递”循环变量
template <std::size_t i>
struct foo{
constexpr void operator()() {
static_assert(i != 3);
}
};
用法:
int main() {
static_for<5,foo>();
}
int main(){
静态_for();
}
或者,您可以使用std::integral_constant
作为参数,这样它就可以与lambdas一起工作,而不需要编写类模板(请参见@Artyer):
#包括
#包括
模板
自动静态\u用于\u impl(F&&F,std::index\u序列){
(静态_-cast(f(std::积分_常数{})),…);
}
模板
(F&&F)的constexpr void static_{
静态_表示_impl(std::forward(f),std::make_index_sequence{});
}
int main(){
([](自动i)的静态_{
静态断言(i!=5);
});
}
在C++20中,您可以使用模板lambda(归功于@Jarod42):
#包括
#包括
模板
(F&&F)的constexpr void static_{
[&f](标准::索引_序列){
(静态_-cast(f(std::积分_常数{})),…);
}(std::make_index_sequence{});
}
int main(){
([](自动i)的静态_{
静态断言(i!=5);
});
}
我不会使用宏来执行此操作。如果您可以通过“传递”循环变量
template <std::size_t i>
struct foo{
constexpr void operator()() {
static_assert(i != 3);
}
};
用法:
int main() {
static_for<5,foo>();
}
int main(){
静态_for();
}
或者,您可以使用std::integral_constant
作为参数,这样它就可以与lambdas一起工作,而不需要编写类模板(请参见@Artyer):
#包括
#包括
模板
自动静态\u用于\u impl(F&&F,std::index\u序列){
(静态_-cast(f(std::积分_常数{})),…);
}
模板
(F&&F)的constexpr void static_{
静态_表示_impl(std::forward(f),std::make_index_sequence{});
}
int main(){
([](自动i)的静态_{
静态断言(i!=5);
});
}
在C++20中,您可以使用模板lambda(归功于@Jarod42):
#包括
#包括
模板
(F&&F)的constexpr void static_{
[&f](标准::索引_序列){
(静态_-cast(f(std::积分_常数{})),…);
}(std::make_index_sequence{});
}
int main(){
([](自动i)的静态_{
静态断言(i!=5);
});
}
我不明白;你能举一个丑陋的手工版本的例子吗?
constexpr
函数已经可以用于循环了。NathanOliver使用i
作为模板参数@cigien添加了一些我不懂的示例代码;你能举一个丑陋的手工版本的例子吗?constexpr
函数已经可以用于循环了。NathanOliver使用i
作为模板参数@cigien添加了一些示例代码,或者使用std::integral_constant
参数调用,因此您可以使用lambdas而不是模板类:@Artyer ah nice。那是我想要的,但我不知道怎么去那里。我将把它添加到答案中,但仅限于tomorrow@Artyer:使用C++20模板lambda。@Jarod42希望您不介意我将您的代码添加到answer@Artyer我在答案中添加了你的代码。它比我的原作好多了,但我还是把它留了下来,只是为了展示不同的方式。我可以想象这样的情况:对类模板的需求不是真正的限制,或者使用std::integral_constant
参数进行调用,因此可以使用lambdas而不是模板类:@Artyer ah nice。那是我想要的,但我不知道怎么去那里。我将把它添加到答案中,但仅限于tomorrow@Artyer:使用C++20模板lambda。@Jarod42希望您不介意我将您的代码添加到answer@Artyer我在答案中添加了你的代码。它比我的原作好多了,但我还是把它留了下来,只是为了展示不同的方式。我可以想象这样的情况:对类模板的需求并不是一个真正的限制
int main() {
static_for<5,foo>();
}
#include <cstddef>
#include <utility>
template<typename F, std::size_t... I>
auto static_for_impl(F&& f, std::index_sequence<I...>) {
(static_cast<void>(f(std::integral_constant<std::size_t, I>{})), ...);
}
template<std::size_t N, typename F>
constexpr void static_for(F&& f) {
static_for_impl<F>(std::forward<F>(f), std::make_index_sequence<N>{});
}
int main() {
static_for<5>([](auto i) {
static_assert(i != 5);
});
}
#include <functional>
#include <utility>
template<std::size_t N, typename F>
constexpr void static_for(F&& f) {
[&f]<std::size_t...Is>(std::index_sequence<Is...>){
(static_cast<void>(f(std::integral_constant<std::size_t, Is>{})), ...);
}(std::make_index_sequence<N>{});
}
int main() {
static_for<5>([](auto i) {
static_assert(i != 5);
});
}