在某些情况下,有一个在编译时评估/展开的
然而,我对如何实现通用的编译时
以下代码实现了这个想法。
虽然代码可以运行,但是最好能够向例程
然而,像下面这样的代码在中无法编译。
for
循环可能是有用/必要的。例如,要迭代tuple
的元素,需要使用std::get<I>
,它依赖于模板int
参数I
,因此必须在编译时进行评估。
使用编译递归可以解决特定问题,例如在这里,这里和特别针对std::tuple
这里中讨论的问题。然而,我对如何实现通用的编译时
for
循环感兴趣。以下代码实现了这个想法。
#include <utility>
#include <tuple>
#include <string>
#include <iostream>
template <int start, int end, template <int> class OperatorType, typename... Args>
void compile_time_for(Args... args)
{
if constexpr (start < end)
{
OperatorType<start>()(std::forward<Args>(args)...);
compile_time_for<start + 1, end, OperatorType>(std::forward<Args>(args)...);
}
}
template <int I>
struct print_tuple_i {
template <typename... U>
void operator()(const std::tuple<U...>& x) { std::cout << std::get<I>(x) << " "; }
};
int main()
{
std::tuple<int, int, std::string> x{1, 2, "hello"};
compile_time_for<0, 3, print_tuple_i>(x);
return 0;
}
虽然代码可以运行,但是最好能够向例程
compile_time_for
提供一个模板函数,而不是在每次迭代中实例化一个模板类。然而,像下面这样的代码在中无法编译。
#include <utility>
#include <tuple>
#include <string>
#include <iostream>
template <int start, int end, template <int, typename...> class F, typename... Args>
void compile_time_for(F f, Args... args)
{
if constexpr (start < end)
{
f<start>(std::forward<Args>(args)...);
compile_time_for<start + 1, end>(f, std::forward<Args>(args)...);
}
}
template <int I, typename... U>
void myprint(const std::tuple<U...>& x) { std::cout << std::get<I>(x) << " "; }
int main()
{
std::tuple<int, int, std::string> x{1, 2, "hello"};
compile_time_for<0, 3>(myprint, x);
return 0;
}
使用gcc 7.3.0和选项std=c++17
,第一个错误是
for2.cpp:7:25: error: ‘auto’ parameter not permitted in this context
void compile_time_for(F f, Args... args)
问题如下:
- 有没有一种方法可以编写
compile_time_for
,使其接受模板函数作为其第一个参数? - 如果问题1的答案是肯定的,那么在第一个工作代码中是否存在开销,因为例程在每个循环迭代中创建一个类型为
OperatorType<start>
的对象? - 是否有计划在即将推出的
c++20
中引入类似于编译时for循环的功能?
std::index_sequence
和std::make_index_sequence
怎么样? - max66std::apply
:std::apply([](const auto&...args) { ((std::cout << args << " "), ...); }, x);
。 - Jarod42std::apply
将无法完成任务。 - francescodecltype(args)
来定义类型。C++20也允许在lambda中使用显式模板。 - Jarod42for...(/*..*/)
。但是我没有成功找到它。 - Jarod42