gpt4 book ai didi

c++ - constexpr 函数中的非 constexpr 调用

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:50 26 4
gpt4 key购买 nike

这是一个简化的代码示例,旨在生成任意值序列(在 std::iota 的意义上)和在它们之上的不同类别的迭代器:

struct delta
{
template<typename I>
void inc(I& i) { ++i; }

template<typename I>
I next(I i) { inc(i); return i; }
};

delta 类有很多,每个类定义inc 的方式不同,例如--i, i += step, i -= step, i *= step, f(i) 等函数 next 保持不变,实际上在基类中共享。

我们正在从 inc 的变异操作中生成 next 的基于值的操作。做相反的事情是等价的,但是我们选择这种设计是为了性能,因为 next 只期望在某些初始化时被调用,而 inc 可能被调用一百万次。

问题是如果某些参数是编译时常量,我想在编译时调用 next 给定 constexpr 参数 i.

这在 C++11 中是不可能的,因为调用了非 constexpr 函数 inc。只需更改为

template<typename I>
constexpr I next(I i) { inc(i); return i; }

template<typename I>
constexpr I next(I i) { return inc(i), i; }

将不起作用。当然,我们可以提供另一个特殊的功能,比如

template<typename I>
constexpr I next(I i) { return i + 1; }

但这样的代码重复太多了,因为有很多类,例如 delta 和许多其他操作,例如 inc/next

我看到 constexpr 函数限制是 relaxed in C++14 , 但我不能 achieve this in practice yet .

所以:

  • 这最终会在 C++14 中工作吗?
  • 标准化的现状如何?
  • 编译器的状态如何?
  • 任何可能的解决方法?

编辑

似乎 inc 也应该是 constexpr(尽管 void)。这works在 clang 3.4 上:

struct delta
{
template<typename I>
constexpr void inc(I& i) { ++i; }

template<typename I>
constexpr I next(I i) { inc(i); return i; }
};

...但不是在 gcc 4.8.2 上。那么上面的代码是正确的 C++14 吗? gcc 只是时间问题吗?

最佳答案

根据这个 page,这个例子在 gcc 上不起作用并不奇怪尚不支持 C++14 的广义 constexpr 函数。

我相信您编辑的源代码是有效的 C++14,可用的标准草案 here在第 126 页(§5.19)包含一个与您的示例非常相似的示例(没有模板、非成员函数并且它们使用临时函数):

constexpr int incr(int &n) {
return ++n;
}

constexpr int g(int k) {
constexpr int x = incr(k);// error: incr(k) is not a core constant
// expression because lifetime of k
// began outside the expression incr(k)
return x;
}

constexpr int h(int k) {
int x = incr(k);
// OK: incr(k) is not required to be a core
// constant expression
return x;
}

constexpr int y = h(1); // OK: initializes y with the value 2
// h(1) is a core constant expression because
// the lifetime of k begins inside h(1)

如果我对标准的理解是正确的,那么你的函数是成员函数这一事实应该无关紧要,因为“this”没有被评估,而且代码似乎没有违反 §5.19 中列出的任何其他规则(2 ).

关于c++ - constexpr 函数中的非 constexpr 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23442942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com