2015-06-10 2 views
17

Насколько я понимаю (по крайней мере, для c++14), деструктор не может быть constexpr, если он не является тривиальным (неявным генерироваться или =default). В чем смысл объявления конструкторов constexpr для структур с нетривиальными деструкторами?почему объявить constrexpr конструктор для классов с нетривиальными деструкторами (например, unique_ptr, станд :: варианта)

struct X { 
    int a_; 

    constexpr X(int a) : a_{a} {} 

    // constexpr ~X(){}; // Error dtor cannot be marked constexpr 
    // ~X(){}; // causes error at y declaration: temporary of non-literal type ‘X’ 
      // in a constant expression . 
}; 

template <int N> struct Y {}; 

int main() { 
    Y<X{3}.a_> y; // OK only if the destructor is trivial 
    (void)y; 
} 
// tested with c++14 g++-5.1.0 and clang++ 3.5.0 

Например std::unique_ptr имеет некоторые constructorsconstexpr (по умолчанию и nullptr_t), даже если деструктор явно явно определен (что он не имеет никакого эффекта, если объект nullptr, но не значит, что она до сих пор явно определенный деструктор, чтобы проверить, находится ли объект в пустом состоянии, и, как я видел, даже пустой деструктор не позволяет использовать объект в выражении с компиляцией)

Другой Например, предложение для std::variant: у него есть почти все конструкторы constexpr, хотя у деструктора есть подпись ~variant() и она должна быть call get<T_j> *this).T_j::~T_j() with j being index().

Что мне не хватает?

+0

См. Также: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2976.html – dyp

+0

Вам не хватает того, что C++ больше не имеет кровавого чувства. –

+0

inb4 lol @ "no longer" –

ответ

16

constexpr конструкторы могут использоваться для постоянной инициализации, которая, как форма статической инициализации, гарантирована, прежде чем произойдет любая динамическая инициализация.

Например, при глобальной std::mutex:

std::mutex mutex; 

В соответствующей реализации (читай: не MSVC), конструкторы других объектов могут безопасно блокировать и разблокировать mutex, потому что конструктор std::mutex «s является constexpr.

+0

Не установлено ли MS, что для VS2015? Кроме того, http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2976.html – dyp

+1

@dyp Не для 'std :: mutex'. –

+0

У вас будет ссылка, где я могу больше узнать об этом? MSDN говорит, что это конструктор 'constexpr', так что * постоянная инициализация * отсутствует в VS2015 или это что-то специфическое для' std :: mutex'? – dyp