- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
如果我想对元组进行迭代,则必须使用疯狂的模板元编程和模板助手特化。例如,以下程序将不起作用:
#include <iostream>
#include <tuple>
#include <utility>
constexpr auto multiple_return_values()
{
return std::make_tuple(3, 3.14, "pi");
}
template <typename T>
constexpr void foo(T t)
{
for (auto i = 0u; i < std::tuple_size<T>::value; ++i)
{
std::get<i>(t);
}
}
int main()
{
constexpr auto ret = multiple_return_values();
foo(ret);
}
i
不能是
const
,否则我们将无法实现它。但是for循环是可以静态评估的编译时构造。借助as-if规则,编译器可以自由地删除,转换,折叠,展开或进行任何操作。但是,为什么不能以constexpr方式使用循环呢?这段代码中没有什么需要在“运行时”完成的。编译器优化就是证明。
i
,但是编译器仍然可以检测到它。例:
// ...snip...
template <typename T>
constexpr int foo(T t)
{
/* Dead code */
for (auto i = 0u; i < std::tuple_size<T>::value; ++i)
{
}
return 42;
}
int main()
{
constexpr auto ret = multiple_return_values();
/* No error */
std::array<int, foo(ret)> arr;
}
std::get<>()
是编译时构造,因此与
std::cout.operator<<
不同,我无法理解为什么不允许这样做。
最佳答案
πάνταῥεῖ给出了一个很好且有用的答案,我想用constexpr for
提到另一个问题。
在C++中,在最基本的级别上,所有表达式都具有可以静态(在编译时)确定的类型。当然有类似RTTI和boost::any
这样的东西,但是它们是在此框架的基础上构建的,表达式的静态类型是理解标准中某些规则的重要概念。
假设您可以使用特殊语法来遍历异构容器,如下所示:
std::tuple<int, float, std::string> my_tuple;
for (const auto & x : my_tuple) {
f(x);
}
f
是一些重载函数。显然,此方法的意图是为元组中的每种类型调用
f
的不同重载。这实际上意味着在表达式
f(x)
中,重载解析必须运行三个不同的时间。如果我们遵循C++的当前规则,那么唯一有意义的方法是在尝试弄清楚表达式的类型之前,将循环基本展开为三个不同的循环体。
for (const auto & x : my_tuple) {
auto y = f(x);
}
auto
不是魔术,它的意思不是“没有类型信息”,而是“请推断出类型,请编译”。但显然,通常确实需要三种不同类型的
y
。
constexpr for
循环进行一些循环展开吗?我不知道,但我认为这可能并不重要。也许有更好的方法...
boost::fusion
或
boost::hana
这样的库可以让您使用给定的vistior对异构序列进行迭代-您可以使用它们的机制而不是for循环。
constexpr for
,例如
for (constexpr i = 0; i < 10; ++i) { ... }
i
用作主体内部的模板参数,则可以在循环主体的不同运行中创建引用不同类型的变量,然后不清楚表达式的静态类型应该是什么。
constexpr for
功能可能会涉及一些非同寻常的技术问题。访客模式/计划的反射功能最终可能会减轻IMO ...的困扰。
std::array<int, 3> a{{1,2,3}};
for (int i = 0; i < 3; ++i) {
auto x = a[i];
int y = 15;
std::cout << &y << std::endl;
}
y
是for循环主体中的局部变量。在整个函数中,它都有一个定义明确的地址,并且每次编译器打印的地址都相同。
std::tuple<int, long double, std::string> a{};
for (int i = 0; i < 3; ++i) {
auto x = std::get<i>(a);
int y = 15;
std::cout << &y << std::endl;
}
x
的类型推导都不同-由于它的类型不同,因此在堆栈上的大小和对齐方式可能不同。由于
y
在堆栈之后,因此
y
可能会在循环的不同运行中更改其地址-对吗?
y
的指针在循环中经过一遍,然后在下一遍中被取消引用,该怎么办?即使在上面显示的
std::array
的类似“no-constexpr for”代码中可能是合法的,也应该是未定义的行为吗?
y
的地址吗?编译器是否应该填充
y
的地址,以便可以在
y
之前容纳元组中最大的类型?这是否意味着编译器不能简单地展开循环并开始生成代码,而是必须事先展开循环的每个实例,然后从每个
N
实例化中收集所有类型信息,然后找到令人满意的布局?
关于c++ - 为什么for循环不是编译时表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37602057/
我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道 哪个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要
我在高中的编程课上,我的作业是制作一个基本的小计和顶级计算器,但我在一家餐馆工作,所以制作一个只能让你在一种食物中读到。因此,我尝试让它能够接收多种食品并将它们添加到一个价格变量中。抱歉,如果某些代码
这是我正在学习的一本教科书。 var ingredients = ["eggs", "milk", "flour", "sugar", "baking soda", "baking powder",
我正在从字符串中提取数字并将其传递给函数。我想给它加 1,然后返回字符串,同时保留前导零。我可以使用 while 循环来完成此操作,但不能使用 for 循环。 for 循环只是跳过零。 var add
编辑:我已经在程序的输出中进行了编辑。 该程序要求估计给定值 mu。用户给出一个值 mu,同时还提供了四个不等于 1 的不同数字(称为 w、x、y、z)。然后,程序尝试使用 de Jaeger 公式找
我正在编写一个算法,该算法对一个整数数组从末尾到开头执行一个大循环,其中包含一个 if 条件。第一次条件为假时,循环可以终止。 因此,对于 for 循环,如果条件为假,它会继续迭代并进行简单的变量更改
现在我已经习惯了在内存非常有限的情况下进行编程,但我没有答案的一个问题是:哪个内存效率更高;- for(;;) 或 while() ?还是它们可以平等互换?如果有的话,还要对效率问题发表评论! 最佳答
这个问题已经有答案了: How do I compare strings in Java? (23 个回答) 已关闭 8 年前。 我正在尝试创建一个小程序,我可以在其中读取该程序的单词。如果单词有 6
这个问题在这里已经有了答案: python : list index out of range error while iteratively popping elements (12 个答案) 关
我正在尝试向用户请求 4 到 10 之间的整数。如果他们回答超出该范围,它将进入循环。当用户第一次正确输入数字时,它不会中断并继续执行 else 语句。如果用户在 else 语句中正确输入数字,它将正
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我想要做的事情是使用循环创建一个数组,然后在另一个类中调用该数组,这不会做,也可能永远不会做。解决这个问题最好的方法是什么?我已经寻找了所有解决方案,但它们无法编译。感谢您的帮助。 import ja
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我正在模拟一家快餐店三个多小时。这三个小时分为 18 个间隔,每个间隔 600 秒。每个间隔都会输出有关这 600 秒内发生的情况的统计信息。 我原来的结构是这样的: int i; for (i=0;
这个问题已经有答案了: IE8 for...in enumerator (3 个回答) How do I check if an object has a specific property in J
哪个对性能更好?这可能与其他编程语言不一致,所以如果它们不同,或者如果你能用你对特定语言的知识回答我的问题,请解释。 我将使用 c++ 作为示例,但我想知道它在 java、c 或任何其他主流语言中的工
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 C 编程和编写代码的新手,以确定 M 测试用例的质因数分解。如果我一次只扫描一次,该功能本身就可以工作,但是当我尝试执行 M 次时却惨遭失败。 我不知道为什么 scanf() 循环有问题。 in
这个问题已经有答案了: JavaScript by reference vs. by value [duplicate] (4 个回答) 已关闭 3 年前。 我在使用 TSlint 时遇到问题,并且理
我尝试在下面的代码中添加 foreach 或 for 循环,以便为 Charts.js 创建多个数据集。这将允许我在此折线图上创建多条线。 我有一个 PHP 对象,我可以对其进行编码以稍后填充变量,但
我是一名优秀的程序员,十分优秀!