我正在尝试在编译时静态实例化一些对象。我需要的是设置成员int变量增量值。例如,我创建的第一个对象将具有0值,第二个为1,第三个为2 ... 总结我需要这样的东西,但它必须像constexpr一样工作。
//header
class MyClass final {
private:
static int IDcount;
public:
const int ID;
constexpr MyClass(args);
//~MyClass();
};
//source
int MyClass::IDcount = 0;
constexpr MyClass::MyClass(args) : ID(MyClass::IDcount++) {
}
有没有办法在编译时实现这一点(不将ID作为构造函数的参数)
答案 0 :(得分:4)
它不能按照你定义它的方式完成,但是有一个非标准但广泛实现的预处理器技巧可以使用。
#include <iostream>
struct MyClass final {
constexpr MyClass(int myid, const char *myname)
: id(myid), name(myname) {}
int id;
const char *name;
};
constexpr MyClass m[]{
MyClass(__COUNTER__, "Larry"),
MyClass(__COUNTER__, "Moe"),
MyClass(__COUNTER__, "Curly")
};
int main()
{
for (auto const &obj : m)
std::cout << obj.id << '\t' << obj.name << "\n";
}
__COUNTER__
宏在Microsoft's Visual C++,gcc since version 4.3和clang中定义。
运行时,该程序会生成:
0 Larry
1 Moe
2 Curly
答案 1 :(得分:3)
constexpr
- 函数或ctor必须是至少一条路径上的有效核心常量表达式:
7.1.5 constexpr说明符
[dcl.constexpr]
5对于非模板,非默认的
constexpr
函数或非模板,非默认的,非继承的constexpr
构造函数,如果不存在参数值,则调用函数或构造函数可以是核心常量表达式的评估子表达式(5.19),程序是不正确的;无需诊断。
这意味着它无法修改所有路径上的全局对象:
5.19常量表达式
[expr.const]
- 醇>
条件表达式
e
是一个核心常量表达式,除非根据抽象机器(1.9)的规则评估e
,以下表达式之一:
- 修改对象(5.17,5.2.6,5.3.2),除非它应用于文字类型的非易失性左值 指的是一个非易失性对象,其生命周期始于
的评估e
;