From 912d191d9848c1918480614dc602003a842b8bb1 Mon Sep 17 00:00:00 2001 From: Aaryaman Sagar Date: Fri, 29 Jul 2016 20:30:00 -0700 Subject: [PATCH] Added initlist_construct_t tag for explicit initializer list Summary: Initializer list construction can often have conflictingly similar syntax as uniform initialization. As a result APIs and classes often either avoid using `std::initializer_list`s or deprecate construction with `std::initializer_list`s. This change provides a tag similar to `std::piecewise_construct_t` to help out. Reviewed By: simpkins Differential Revision: D3617276 fbshipit-source-id: 3c74802f946a22e1a4ee52eca0f89df4a028eb22 --- folly/Traits.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/folly/Traits.h b/folly/Traits.h index 6ea1c4b1..c50948cc 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -405,6 +405,51 @@ bool greater_than(LHS const lhs) { struct construct_in_place_t {}; constexpr construct_in_place_t construct_in_place{}; +/** + * Initializer lists are a powerful compile time syntax introduced in C++11 + * but due to their often conflicting syntax they are not used by APIs for + * construction. + * + * Further standard conforming compilers *strongly* favor an + * std::initalizer_list overload for construction if one exists. The + * following is a simple tag used to disambiguate construction with + * initializer lists and regular uniform initialization. + * + * For example consider the following case + * + * class Something { + * public: + * explicit Something(int); + * Something(std::intiializer_list); + * + * operator int(); + * }; + * + * ... + * Something something{1}; // SURPRISE!! + * + * The last call to instantiate the Something object will go to the + * initializer_list overload. Which may be surprising to users. + * + * If however this tag was used to disambiguate such construction it would be + * easy for users to see which construction overload their code was referring + * to. For example + * + * class Something { + * public: + * explicit Something(int); + * Something(folly::initlist_construct_t, std::initializer_list); + * + * operator int(); + * }; + * + * ... + * Something something_one{1}; // not the initializer_list overload + * Something something_two{folly::initlist_construct, {1}}; // correct + */ +struct initlist_construct_t {}; +constexpr initlist_construct_t initlist_construct{}; + } // namespace folly // gcc-5.0 changed string's implementation in libgcc to be non-relocatable -- 2.34.1