2

iota函数以前位于<algorithm>标题中。已更改为<numeric>.

我需要保留旧方法以实现向后兼容性,因此我想使用预处理器选项来选择要包含的正确标头。

这什么时候改变了,我应​​该使用哪个预处理器选项?

4

3 回答 3

4

iota was never "moved" from <algorithm>. C++03 doesn't have std::iota in any header, and no conforming implementation can provide it, because iota is not a reserved name and this is required to work:

#define iota arbitrary preprocessing token sequence like this and *that and "!" and \
             -13833rfa231fn7or.other.line.noise.that.happens.to.be.a.pp.number
#include <every-standard-header-here>

It was added to <numeric> in C++11 and was in the SGI STL's <numeric> too as an extension. It has never been in <algorithm> and so can't possibly be moved from it.

现在,因为允许标准库头文件以任意方式相互包含,所以碰巧<algorithm>在 C++11 模式下的 GCC <= 5's 包含<random>在偶然事件中,其中包含<numeric>偶然事件。这仅仅是您不应该依赖的实现细节,而 GCC 6 不再这样做。解决这个问题的方法是简单地包含正确的标题,它是并且一直是<numeric>.

于 2017-03-22T20:10:19.890 回答
1

iota (来自希腊语 ι)在<numeric>到来时被重新引入,正如您在ref中看到的那样。因此,您检查您是否在没有它的环境中,并包含旧标题,或者包含新标题。

这样的事情可能会奏效:

#if __cplusplus <= 199711L
  #include <algorithm>
#else
  #include <numeric>
#endif

将 的值设置__cplusplus201103L。这表明完全符合 2011 年标准;它不会告诉您有关部分一致性或编译器扩展的信息。如果__cplusplus设置为 201103L,则编译器要么完全符合,要么在骗你。如果不是,那么您无法真正分辨它支持哪些功能。

在这个答案中阅读更多内容。

此外,这篇 Quora帖子也同意std::iota发生的变化(或者说实话;重新引入)。


如果您负担得起,只需包含这两个库。

于 2017-03-22T18:32:02.030 回答
1

你想要做的是检查__cplusplus变量是否低于某个点,#include <algorithm>如果不是,那么#include <numeric>

#if __cplusplus <= 199711L
  #include <algorithm>
#else
  #include <numeric>
#endif

This should work for just about any library that you need to do this with, just note that you may have to change the 199711L to the appropriate number.

于 2017-03-22T18:34:36.680 回答