C ++ constexpr计数构造函数调用

时间:2014-10-23 13:44:57

标签: c++ instantiation constexpr

我正在尝试在编译时静态实例化一些对象。我需要的是设置成员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作为构造函数的参数)

2 个答案:

答案 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.3clang中定义。

运行时,该程序会生成:

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]

     
      
  1. 条件表达式 e是一个核心常量表达式,除非根据抽象机器(1.9)的规则评估e,以下表达式之一:

         
        
    • 修改对象(5.17,5.2.6,5.3.2),除非它应用于文字类型的非易失性左值   指的是一个非易失性对象,其生命周期始于e;
    • 的评估   
  2.