【发布时间】:2015-10-22 11:24:57
【问题描述】:
假设我想在编译时使用某种算法构建一个图,然后计算图中最终有多少节点。这似乎是 constexpr 的理想情况,而不是模板元编程,因为目标是产生值的计算,而不是真正的类型。我有一些可以工作的代码,但这个功能太新了,我担心编译器会很宽松,我可以将部分标准解释为我不能这样做。
#include <iostream>
struct A { int x; constexpr A(int i) noexcept : x{i} {} };
struct B { A& a; constexpr B(A& a) noexcept : a{a} {} };
constexpr int foo() {
A a{55};
B b{a};
return b.a.x;
}
template<int N>
void output()
{
std::cout << N << std::endl;
}
int main() {
// to be absolutely sure compile time eval'd,
// pass as template arg
constexpr auto b = foo();
output<b>();
}
a 和b 实例都是在编译时创建的,它们具有相同的生命周期,因此这应该是“安全的”。但是a 是一个非静态对象,this part of the standard 似乎说这是不允许的:
一个实体是一个常量表达式的允许结果,如果它是一个 具有不是临时的静态存储持续时间的对象 对象或者是一个临时对象,其值满足上述条件 约束,或者它是一个函数。
那我可以还是不能? GCC and clang are both fine with it.
【问题讨论】:
-
该代码通常不会有问题,因为在编译时不使用结果。
constexpr函数没有具有 来生成编译时间常数。当提供编译时常量参数(如果有)时,它可以做到这一点。不过不确定你的情况。但呈现的代码并没有锻炼编译时间常数。 -
@Jarod42:监督,现在改了,结果一样。
-
@Cheersandhth.-Alf:我已将 constexpr 添加到 'b' 的主要声明中以强制它为编译时间。
-
而
A a{55};可能是constexpr,B b{a};不能是(带有clang 错误消息note: reference to 'a' is not a constant expression)Demo
标签: c++ metaprogramming standards c++14 constexpr