How can I detect that a constuctor is really constexpr, so I can utilize static initialization?

允我心安 提交于 2019-12-20 04:16:46

问题


Look at this code:

struct NonConstexpr {
    NonConstexpr() { }
};

template <typename T>
struct Bar {
    NonConstexpr nonConstexpr;

    constexpr Bar() { }
};

struct Foo {
    Bar<void> bar;

    constexpr Foo() { }
};

In this code, Foo's constructor is tagged as constexpr, but it cannot appear in a constant expression, as it actually fails to satisfy the requirements of this. You can read the details of this in my previous question.

My question is: can I detect somehow compile-time, that Foo's constructor actually won't behave as constexpr?

The reason I ask this, I'd like to detect that a global variable of Foo will be statically initialized or not (I'd like to put a static_assert on this, as my global Foo object must be initialized statically).

Note, that the straightforward solution, to temporarily add constexpr to the variable doesn't work, as my Foo has a non-trivial destructor.


回答1:


If you are using Clang, use [[clang::require_constant_initialization]] on the variable. Otherwise, I don't know of a way.

The committee is looking at standardizing this as a keyword.




回答2:


The only (current, toolchain-independent) way to prevent the compiler dropping the constexpr silently that I'm aware of, is to assign to a 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;
}

... will fail to compile with constexpr constructor calls non-constexpr function "Bar<T>::Bar() [with T=void]"



来源:https://stackoverflow.com/questions/53632120/how-can-i-detect-that-a-constuctor-is-really-constexpr-so-i-can-utilize-static

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!