Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于constexpr函数中的constexpr_C++_C++20 - Fatal编程技术网

C++ 对于constexpr函数中的constexpr

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

我正在编写一个constexpr函数,需要使用一个constexpr函数。循环可以手动扩展,但我发现代码很难看,而且冗余

我怎样才能做一个“constexpr for”

我应该创建一个助手类吗?如果是这样的话,我该怎么写这样的东西:

#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);
    });
}