代码之家  ›  专栏  ›  技术社区  ›  geza

我如何检测一个构造器是否真的是constexpr,以便使用静态初始化?

  •  1
  • geza  · 技术社区  · 6 年前

    查看此代码:

    struct NonConstexpr {
        NonConstexpr() { }
    };
    
    template <typename T>
    struct Bar {
        NonConstexpr nonConstexpr;
    
        constexpr Bar() { }
    };
    
    struct Foo {
        Bar<void> bar;
    
        constexpr Foo() { }
    };
    

    在本代码中, Foo 的构造函数标记为 constexpr 但它不能出现在常量表达式中,因为它实际上无法满足这一要求。你可以在我的 previous question .

    我的问题是:我能检测到编译时间吗? 的构造函数实际上不会 常量表达式 ?

    我问这个的原因,我想检测一个全局变量 是否静态初始化(我希望 static_assert 关于这个,作为我的全球 FOO公司 对象必须静态初始化)。

    注意,直截了当的解决方案,暂时添加 常量表达式 对变量不起作用,因为 有一个非平凡的析构函数。

    2 回复  |  直到 6 年前
        1
  •  2
  •   T.C. Yksisarvinen    6 年前

    如果您使用clang,请使用 [[clang::require_constant_initialization]] 在变量上。否则,我不知道怎么办。

    委员会正考虑将这一标准化为一个关键词。

        2
  •  1
  •   Fubert    6 年前

    唯一(当前的、与工具链无关的)防止编译器悄悄地删除constexpr的方法是分配给constexpr:

    struct NonConstexpr {
        NonConstexpr() { }
    };
    
    template <typename T>
    struct Bar {
        NonConstexpr nonConstexpr;
    
        constexpr Bar() { }
    };
    
    struct Foo {
        Bar<void> bar;
    
        constexpr Foo() { }
    };
    
    int main()
    {
        constexpr auto f = Foo();
        return 0;
    }
    

    …无法编译 constexpr constructor calls non-constexpr function "Bar<T>::Bar() [with T=void]"