constexpr函数中的非constexpr调用
non-constexpr calls in constexpr functions
这是一个简化的代码示例,用于生成任意值序列(在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
函数限制将在c++ 14中放松,但我还不能在实践中实现这一点。
:
- 这最终会在c++ 14中工作吗?
- 标准化的现状如何? 编译器的状态是什么?
- 有任何可能的解决方案吗?
编辑
似乎inc
也应该是constexpr
(虽然void
)。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来说,这只是时间问题吗?
这个例子不能在gcc上工作并不奇怪,根据本页,c++ 14的广义constexpr函数还不受支持。
我相信你编辑的源代码是有效的c++ 14,这里的标准草案包含,在第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)中列出的任何其他规则。
- 在 constexpr funnction 中调用basic_string函数
- 调用模板参数 constexpr 方法?
- 在模板定义中调用非静态constexpr成员函数
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 在enable_if_t中调用 constexpr 函数
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?
- 对 constexpr 与内联函数的调用编译为不同的程序集,并禁用优化
- constexpr vs重复函数调用性能
- 触发编译时间错误时,constexpr函数的超载被调用
- 为什么 gcc5.4 不编译调用非 constexpr 函数的 constexpr 函数,而 icpc 可以编译?
- 模板推导指南可以调用constexpr函数吗
- 如何在constexpr函数中有效地调用_BitScanReverse或__builtin_clz
- 当编译时参数未知时,不调用"constexpr"构造函数
- 为什么我可以在constexpr函数中调用一个非constexpr的函数
- 在常量表达式上下文中的定义之前嵌套的“constexpr”函数调用
- 为什么调用此constexpr静态成员函数时不将其视为constexpr
- 只要调用的函数是用constexpr指定的,就将委托方法声明为constexpr
- C++标准是否明确禁止通过 constexpr 成员函数指针调用默认参数?
- 在默认模板参数中调用 constexpr
- constexpr函数中的非constexpr调用