//Purpose: // Demonstrate limitations of using constexpr // with aligned_union implementation of variant. //References: // [N3797[expr.const]/p2] // Paper: // https://isocpp.org/files/papers/N3797.pdf // Section: // 5.19 Constant Expresssions [expr.const] // Paragraph: // 2 //================================================= #include #include using storage_char_t //Purpose: // Provide alias for // decltype(aligned_union::type::_s[0]) // making it easy to declare any of Types... // as the same. =char; //{aligned_union //Source: // The following (to //}aligned_union) is a slight // modification of code in the section headed by // "Possible implementation" here: // http://en.cppreference.com/w/cpp/types/aligned_union // at 2015-04-09.0503CST. #include template struct aligned_union { static constexpr std::size_t alignment_value = std::max({alignof(Types)...}); static std::size_t constexpr size_value =std::max({Len, sizeof(Types)...}); struct type { alignas(alignment_value) storage_char_t _s[size_value]; constexpr type() : _s() { //for(unsigned i=0; i struct variant { using storage_var_t=typename aligned_union<1,Head>::type; storage_var_t my_storage; constexpr variant(Head h) { //#define USE_PLACEMENT_NEW #ifdef USE_PLACEMENT_NEW new(my_storage._s) Head(h); //This violates restriction in reference: // [N3797[expr.const]/p2] //in the bullet starting with: // — a new-expression (5.3.4); #else my_storage._s[0]=h; #endif } constexpr Head get()const { return * static_cast ( static_cast //#define USE_STATIC_CAST_VOID #ifdef USE_STATIC_CAST_VOID < void //This violates restriction in reference: // [N3797[expr.const]/p2] //in the bullet starting with: // — a conversion from type cv void * #else < Head #endif const* > ( my_storage._s ) ); } }; int main() { auto is_alu_lit=std::is_literal_type::type>::type::value; std::cout<<"is_alu_lit="< var_v('a'); std::cout<<"get="<(var_v.my_storage._s); constexpr storage_char_t char0=var_v.get(); return 0; }