Why does using uniform initializer syntax result in different behavior to the “old” style ()?std::set deduction guide doesn't work as expectedHow do I achieve the theoretical maximum of 4 FLOPs per cycle?Why doesn't emplace_back() use uniform initialization?Why does 'std::vector<int> b2;' create a 1-element vector, and not a 2-element one?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsFirst time working with classes in C++ : request for member of non class typeHow does “std::cout << std::endl;” compile?Does the C++ standard guarantee that uniform initialization is exception-safe?C++ Trouble compiling cout with a += statementc++ 1z error: error: explicit qualification in declaration in deduction guideUniform Initialization Syntax Not Working on Visual Studio 2012

How certain is a caster of when their spell will end?

What are the words for people who cause trouble believing they know better?

What do we gain with higher order logics?

Is it a problem that pull requests are approved without any comments

Is there any word or phrase for negative bearing?

Does the growth of home value benefit from compound interest?

Is it OK to bring delicacies from hometown as tokens of gratitude for an out-of-town interview?

The ring of global sections of a regular scheme

Secure offsite backup, even in the case of hacker root access

Is it possible for people to live in the eye of a permanent hypercane?

How bad would a partial hash leak be, realistically?

How do you build a story from a world?

What happened to all the nuclear material being smuggled after the fall of the USSR?

What is the purpose of building foundations?

Why don't B747s start takeoffs with full throttle?

Did thousands of women die every year due to illegal abortions before Roe v. Wade?

Who operates delivery flights for commercial airlines?

Responsibility for visa checking

What are the words for people who cause trouble believing they know better?

Credit card offering 0.5 miles for every cent rounded up. Too good to be true?

What's the correct term for a waitress in the Middle Ages?

Do I include animal companions when calculating difficulty of an encounter?

I wrote a scene that the majority of my readers loved. How do I get back to that place while writing my new book?

If Boris Johnson were prosecuted and convicted of lying about Brexit, can that be used to cancel Brexit?



Why does using uniform initializer syntax result in different behavior to the “old” style ()?


std::set deduction guide doesn't work as expectedHow do I achieve the theoretical maximum of 4 FLOPs per cycle?Why doesn't emplace_back() use uniform initialization?Why does 'std::vector<int> b2;' create a 1-element vector, and not a 2-element one?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsFirst time working with classes in C++ : request for member of non class typeHow does “std::cout << std::endl;” compile?Does the C++ standard guarantee that uniform initialization is exception-safe?C++ Trouble compiling cout with a += statementc++ 1z error: error: explicit qualification in declaration in deduction guideUniform Initialization Syntax Not Working on Visual Studio 2012






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








7















I get different results if I try to use a uniform initializer for std::set.



Example:



int main()

std::array a 1,2,3,4;
std::set<int> s1 a.begin(), a.end();
std::set s2 a.begin(), a.end();
std::set s3 (a.begin(), a.end());

for(auto& i: s1) std::cout << i << "n";
std::cout << "####" << std::endl;
for(auto& i: s2) std::cout << i << "n";
std::cout << "####" << std::endl;
for(auto& i: s3) std::cout << i << "n";



Results in:



1 
2
3
4
####
0x7ffecf9d12e0
0x7ffecf9d12f0
####
1
2
3
4


This seems to be related to "deduction guides", which are evaluated differently if used with or () syntax.










share|improve this question






























    7















    I get different results if I try to use a uniform initializer for std::set.



    Example:



    int main()

    std::array a 1,2,3,4;
    std::set<int> s1 a.begin(), a.end();
    std::set s2 a.begin(), a.end();
    std::set s3 (a.begin(), a.end());

    for(auto& i: s1) std::cout << i << "n";
    std::cout << "####" << std::endl;
    for(auto& i: s2) std::cout << i << "n";
    std::cout << "####" << std::endl;
    for(auto& i: s3) std::cout << i << "n";



    Results in:



    1 
    2
    3
    4
    ####
    0x7ffecf9d12e0
    0x7ffecf9d12f0
    ####
    1
    2
    3
    4


    This seems to be related to "deduction guides", which are evaluated differently if used with or () syntax.










    share|improve this question


























      7












      7








      7








      I get different results if I try to use a uniform initializer for std::set.



      Example:



      int main()

      std::array a 1,2,3,4;
      std::set<int> s1 a.begin(), a.end();
      std::set s2 a.begin(), a.end();
      std::set s3 (a.begin(), a.end());

      for(auto& i: s1) std::cout << i << "n";
      std::cout << "####" << std::endl;
      for(auto& i: s2) std::cout << i << "n";
      std::cout << "####" << std::endl;
      for(auto& i: s3) std::cout << i << "n";



      Results in:



      1 
      2
      3
      4
      ####
      0x7ffecf9d12e0
      0x7ffecf9d12f0
      ####
      1
      2
      3
      4


      This seems to be related to "deduction guides", which are evaluated differently if used with or () syntax.










      share|improve this question
















      I get different results if I try to use a uniform initializer for std::set.



      Example:



      int main()

      std::array a 1,2,3,4;
      std::set<int> s1 a.begin(), a.end();
      std::set s2 a.begin(), a.end();
      std::set s3 (a.begin(), a.end());

      for(auto& i: s1) std::cout << i << "n";
      std::cout << "####" << std::endl;
      for(auto& i: s2) std::cout << i << "n";
      std::cout << "####" << std::endl;
      for(auto& i: s3) std::cout << i << "n";



      Results in:



      1 
      2
      3
      4
      ####
      0x7ffecf9d12e0
      0x7ffecf9d12f0
      ####
      1
      2
      3
      4


      This seems to be related to "deduction guides", which are evaluated differently if used with or () syntax.







      c++ c++17 uniform-initialization






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 26 at 12:40









      Boann

      38k1291123




      38k1291123










      asked May 26 at 11:37









      KlausKlaus

      11.5k13064




      11.5k13064






















          1 Answer
          1






          active

          oldest

          votes


















          7














          Short answer



          For s2, brace syntax is used, and a.begin(), a.end() is considered to be an initializer_list of std::array<int>::iterators. Therefore, s2 is a set of iterators.



          For s3, parentheses syntax is used, and the iterator constructor is selected. s3 is a set of ints, and is initialized from the range [a.begin(), a.end()).



          Long answer



          Per [set.overview], we have two deduction guides relevant here:




          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          set(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;



          and




          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;




          Per [over.match.class.deduct]/1:




          A set of functions and function templates is formed comprising:



          • [...]



          • (1.4) For each deduction-guide, a function or function template with the following properties:



            • The template parameters, if any, and function parameters are those of the deduction-guide.


            • The return type is the simple-template-id of the deduction-guide.





          In this case, the synthesized functions and function templates for the aforementioned deduction guides are, respectively,



          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          auto __func1(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;


          and



          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          auto __func2(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;


          (I used double underscores to signify that these names are synthesized, and are not otherwise accessible.)




          Per [over.match.class.deduct]/2:




          Initialization and overload resolution are performed as described in
          [dcl.init] and [over.match.ctor], [over.match.copy], or
          [over.match.list] (as appropriate for the type of initialization
          performed) for an object of a hypothetical class type, where the
          selected functions and function templates are considered to be the
          constructors of that class type for the purpose of forming an overload
          set, and the initializer is provided by the context in which class
          template argument deduction was performed. Each such notional
          constructor is considered to be explicit if the function or function
          template was generated from a constructor or deduction-guide that
          was declared explicit. All such notional constructors are considered
          to be public members of the hypothetical class type.




          The hypothetical class type looks like:



          class __hypothetical 
          public:
          // ...

          // #1
          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          __hypothetical(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

          // #2
          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          __hypothetical(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;

          // ...
          ;



          For the declaration of s2,



          std::set s2 a.begin(), a.end();


          The overload resolution is performed as if in



          __hypothetical __hypa.begin(), a.end(); // braces


          Thus, [over.match.list] comes in.




          [...] overload resolution selects the constructor in two phases:



          • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list
            consists of the initializer list as a single argument.


          • [...]




          Constructor #2 is an initializer-list constructor. Function template argument deduction gives



          Key = std::array<int>::iterator


          So the deduced type of s2 is



          std::set<std::array<int>::iterator>


          The declaration of s2 is equivalent to



          std::set<std::array<int>::iterator> s2 a.begin(), a.end();


          Therefore, s2 is a set of iterators that consists of two elements: a.begin() and a.end(). In your case, std::array<int>::iterator is probably int*, and a.begin() and a.end() happen to be serialized as 0x7ffecf9d12e0 and 0x7ffecf9d12f0, respectively.




          For s3, overload resolution is performed as if in



          __hypothetical __hyp(a.begin(), a.end()); // parentheses


          That's direct-initialization, and is under the scope of [pver.match.ctor]. The initializer_list constructor is irrelevant, and the Constructor #1 is selected instead. Function template argument deduction gives



          InputIterator = std::array<int>::iterator


          So the deduced type of s3 is



          set<iterator_traits<std::array<int>::iterator>::value_type>


          Which is set<int>. Therefore, the declaration of s3 is equivalent to



          std::set<int> s3 (a.begin(), a.end());


          s3 is a set of ints that is initialized from the range [a.begin(), a.end()) — four elements 1, 2, 3, 4, which explains the output.






          share|improve this answer

























          • @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

            – Holt
            May 26 at 11:48












          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56313139%2fwhy-does-using-uniform-initializer-syntax-result-in-different-behavior-to-the-o%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          7














          Short answer



          For s2, brace syntax is used, and a.begin(), a.end() is considered to be an initializer_list of std::array<int>::iterators. Therefore, s2 is a set of iterators.



          For s3, parentheses syntax is used, and the iterator constructor is selected. s3 is a set of ints, and is initialized from the range [a.begin(), a.end()).



          Long answer



          Per [set.overview], we have two deduction guides relevant here:




          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          set(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;



          and




          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;




          Per [over.match.class.deduct]/1:




          A set of functions and function templates is formed comprising:



          • [...]



          • (1.4) For each deduction-guide, a function or function template with the following properties:



            • The template parameters, if any, and function parameters are those of the deduction-guide.


            • The return type is the simple-template-id of the deduction-guide.





          In this case, the synthesized functions and function templates for the aforementioned deduction guides are, respectively,



          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          auto __func1(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;


          and



          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          auto __func2(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;


          (I used double underscores to signify that these names are synthesized, and are not otherwise accessible.)




          Per [over.match.class.deduct]/2:




          Initialization and overload resolution are performed as described in
          [dcl.init] and [over.match.ctor], [over.match.copy], or
          [over.match.list] (as appropriate for the type of initialization
          performed) for an object of a hypothetical class type, where the
          selected functions and function templates are considered to be the
          constructors of that class type for the purpose of forming an overload
          set, and the initializer is provided by the context in which class
          template argument deduction was performed. Each such notional
          constructor is considered to be explicit if the function or function
          template was generated from a constructor or deduction-guide that
          was declared explicit. All such notional constructors are considered
          to be public members of the hypothetical class type.




          The hypothetical class type looks like:



          class __hypothetical 
          public:
          // ...

          // #1
          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          __hypothetical(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

          // #2
          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          __hypothetical(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;

          // ...
          ;



          For the declaration of s2,



          std::set s2 a.begin(), a.end();


          The overload resolution is performed as if in



          __hypothetical __hypa.begin(), a.end(); // braces


          Thus, [over.match.list] comes in.




          [...] overload resolution selects the constructor in two phases:



          • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list
            consists of the initializer list as a single argument.


          • [...]




          Constructor #2 is an initializer-list constructor. Function template argument deduction gives



          Key = std::array<int>::iterator


          So the deduced type of s2 is



          std::set<std::array<int>::iterator>


          The declaration of s2 is equivalent to



          std::set<std::array<int>::iterator> s2 a.begin(), a.end();


          Therefore, s2 is a set of iterators that consists of two elements: a.begin() and a.end(). In your case, std::array<int>::iterator is probably int*, and a.begin() and a.end() happen to be serialized as 0x7ffecf9d12e0 and 0x7ffecf9d12f0, respectively.




          For s3, overload resolution is performed as if in



          __hypothetical __hyp(a.begin(), a.end()); // parentheses


          That's direct-initialization, and is under the scope of [pver.match.ctor]. The initializer_list constructor is irrelevant, and the Constructor #1 is selected instead. Function template argument deduction gives



          InputIterator = std::array<int>::iterator


          So the deduced type of s3 is



          set<iterator_traits<std::array<int>::iterator>::value_type>


          Which is set<int>. Therefore, the declaration of s3 is equivalent to



          std::set<int> s3 (a.begin(), a.end());


          s3 is a set of ints that is initialized from the range [a.begin(), a.end()) — four elements 1, 2, 3, 4, which explains the output.






          share|improve this answer

























          • @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

            – Holt
            May 26 at 11:48
















          7














          Short answer



          For s2, brace syntax is used, and a.begin(), a.end() is considered to be an initializer_list of std::array<int>::iterators. Therefore, s2 is a set of iterators.



          For s3, parentheses syntax is used, and the iterator constructor is selected. s3 is a set of ints, and is initialized from the range [a.begin(), a.end()).



          Long answer



          Per [set.overview], we have two deduction guides relevant here:




          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          set(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;



          and




          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;




          Per [over.match.class.deduct]/1:




          A set of functions and function templates is formed comprising:



          • [...]



          • (1.4) For each deduction-guide, a function or function template with the following properties:



            • The template parameters, if any, and function parameters are those of the deduction-guide.


            • The return type is the simple-template-id of the deduction-guide.





          In this case, the synthesized functions and function templates for the aforementioned deduction guides are, respectively,



          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          auto __func1(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;


          and



          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          auto __func2(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;


          (I used double underscores to signify that these names are synthesized, and are not otherwise accessible.)




          Per [over.match.class.deduct]/2:




          Initialization and overload resolution are performed as described in
          [dcl.init] and [over.match.ctor], [over.match.copy], or
          [over.match.list] (as appropriate for the type of initialization
          performed) for an object of a hypothetical class type, where the
          selected functions and function templates are considered to be the
          constructors of that class type for the purpose of forming an overload
          set, and the initializer is provided by the context in which class
          template argument deduction was performed. Each such notional
          constructor is considered to be explicit if the function or function
          template was generated from a constructor or deduction-guide that
          was declared explicit. All such notional constructors are considered
          to be public members of the hypothetical class type.




          The hypothetical class type looks like:



          class __hypothetical 
          public:
          // ...

          // #1
          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          __hypothetical(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

          // #2
          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          __hypothetical(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;

          // ...
          ;



          For the declaration of s2,



          std::set s2 a.begin(), a.end();


          The overload resolution is performed as if in



          __hypothetical __hypa.begin(), a.end(); // braces


          Thus, [over.match.list] comes in.




          [...] overload resolution selects the constructor in two phases:



          • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list
            consists of the initializer list as a single argument.


          • [...]




          Constructor #2 is an initializer-list constructor. Function template argument deduction gives



          Key = std::array<int>::iterator


          So the deduced type of s2 is



          std::set<std::array<int>::iterator>


          The declaration of s2 is equivalent to



          std::set<std::array<int>::iterator> s2 a.begin(), a.end();


          Therefore, s2 is a set of iterators that consists of two elements: a.begin() and a.end(). In your case, std::array<int>::iterator is probably int*, and a.begin() and a.end() happen to be serialized as 0x7ffecf9d12e0 and 0x7ffecf9d12f0, respectively.




          For s3, overload resolution is performed as if in



          __hypothetical __hyp(a.begin(), a.end()); // parentheses


          That's direct-initialization, and is under the scope of [pver.match.ctor]. The initializer_list constructor is irrelevant, and the Constructor #1 is selected instead. Function template argument deduction gives



          InputIterator = std::array<int>::iterator


          So the deduced type of s3 is



          set<iterator_traits<std::array<int>::iterator>::value_type>


          Which is set<int>. Therefore, the declaration of s3 is equivalent to



          std::set<int> s3 (a.begin(), a.end());


          s3 is a set of ints that is initialized from the range [a.begin(), a.end()) — four elements 1, 2, 3, 4, which explains the output.






          share|improve this answer

























          • @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

            – Holt
            May 26 at 11:48














          7












          7








          7







          Short answer



          For s2, brace syntax is used, and a.begin(), a.end() is considered to be an initializer_list of std::array<int>::iterators. Therefore, s2 is a set of iterators.



          For s3, parentheses syntax is used, and the iterator constructor is selected. s3 is a set of ints, and is initialized from the range [a.begin(), a.end()).



          Long answer



          Per [set.overview], we have two deduction guides relevant here:




          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          set(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;



          and




          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;




          Per [over.match.class.deduct]/1:




          A set of functions and function templates is formed comprising:



          • [...]



          • (1.4) For each deduction-guide, a function or function template with the following properties:



            • The template parameters, if any, and function parameters are those of the deduction-guide.


            • The return type is the simple-template-id of the deduction-guide.





          In this case, the synthesized functions and function templates for the aforementioned deduction guides are, respectively,



          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          auto __func1(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;


          and



          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          auto __func2(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;


          (I used double underscores to signify that these names are synthesized, and are not otherwise accessible.)




          Per [over.match.class.deduct]/2:




          Initialization and overload resolution are performed as described in
          [dcl.init] and [over.match.ctor], [over.match.copy], or
          [over.match.list] (as appropriate for the type of initialization
          performed) for an object of a hypothetical class type, where the
          selected functions and function templates are considered to be the
          constructors of that class type for the purpose of forming an overload
          set, and the initializer is provided by the context in which class
          template argument deduction was performed. Each such notional
          constructor is considered to be explicit if the function or function
          template was generated from a constructor or deduction-guide that
          was declared explicit. All such notional constructors are considered
          to be public members of the hypothetical class type.




          The hypothetical class type looks like:



          class __hypothetical 
          public:
          // ...

          // #1
          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          __hypothetical(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

          // #2
          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          __hypothetical(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;

          // ...
          ;



          For the declaration of s2,



          std::set s2 a.begin(), a.end();


          The overload resolution is performed as if in



          __hypothetical __hypa.begin(), a.end(); // braces


          Thus, [over.match.list] comes in.




          [...] overload resolution selects the constructor in two phases:



          • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list
            consists of the initializer list as a single argument.


          • [...]




          Constructor #2 is an initializer-list constructor. Function template argument deduction gives



          Key = std::array<int>::iterator


          So the deduced type of s2 is



          std::set<std::array<int>::iterator>


          The declaration of s2 is equivalent to



          std::set<std::array<int>::iterator> s2 a.begin(), a.end();


          Therefore, s2 is a set of iterators that consists of two elements: a.begin() and a.end(). In your case, std::array<int>::iterator is probably int*, and a.begin() and a.end() happen to be serialized as 0x7ffecf9d12e0 and 0x7ffecf9d12f0, respectively.




          For s3, overload resolution is performed as if in



          __hypothetical __hyp(a.begin(), a.end()); // parentheses


          That's direct-initialization, and is under the scope of [pver.match.ctor]. The initializer_list constructor is irrelevant, and the Constructor #1 is selected instead. Function template argument deduction gives



          InputIterator = std::array<int>::iterator


          So the deduced type of s3 is



          set<iterator_traits<std::array<int>::iterator>::value_type>


          Which is set<int>. Therefore, the declaration of s3 is equivalent to



          std::set<int> s3 (a.begin(), a.end());


          s3 is a set of ints that is initialized from the range [a.begin(), a.end()) — four elements 1, 2, 3, 4, which explains the output.






          share|improve this answer















          Short answer



          For s2, brace syntax is used, and a.begin(), a.end() is considered to be an initializer_list of std::array<int>::iterators. Therefore, s2 is a set of iterators.



          For s3, parentheses syntax is used, and the iterator constructor is selected. s3 is a set of ints, and is initialized from the range [a.begin(), a.end()).



          Long answer



          Per [set.overview], we have two deduction guides relevant here:




          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          set(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;



          and




          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;




          Per [over.match.class.deduct]/1:




          A set of functions and function templates is formed comprising:



          • [...]



          • (1.4) For each deduction-guide, a function or function template with the following properties:



            • The template parameters, if any, and function parameters are those of the deduction-guide.


            • The return type is the simple-template-id of the deduction-guide.





          In this case, the synthesized functions and function templates for the aforementioned deduction guides are, respectively,



          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          auto __func1(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;


          and



          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          auto __func2(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;


          (I used double underscores to signify that these names are synthesized, and are not otherwise accessible.)




          Per [over.match.class.deduct]/2:




          Initialization and overload resolution are performed as described in
          [dcl.init] and [over.match.ctor], [over.match.copy], or
          [over.match.list] (as appropriate for the type of initialization
          performed) for an object of a hypothetical class type, where the
          selected functions and function templates are considered to be the
          constructors of that class type for the purpose of forming an overload
          set, and the initializer is provided by the context in which class
          template argument deduction was performed. Each such notional
          constructor is considered to be explicit if the function or function
          template was generated from a constructor or deduction-guide that
          was declared explicit. All such notional constructors are considered
          to be public members of the hypothetical class type.




          The hypothetical class type looks like:



          class __hypothetical 
          public:
          // ...

          // #1
          template<class InputIterator,
          class Compare = less<typename iterator_traits<InputIterator>::value_type>,
          class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
          __hypothetical(InputIterator, InputIterator,
          Compare = Compare(), Allocator = Allocator())
          -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

          // #2
          template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
          __hypothetical(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
          -> set<Key, Compare, Allocator>;

          // ...
          ;



          For the declaration of s2,



          std::set s2 a.begin(), a.end();


          The overload resolution is performed as if in



          __hypothetical __hypa.begin(), a.end(); // braces


          Thus, [over.match.list] comes in.




          [...] overload resolution selects the constructor in two phases:



          • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list
            consists of the initializer list as a single argument.


          • [...]




          Constructor #2 is an initializer-list constructor. Function template argument deduction gives



          Key = std::array<int>::iterator


          So the deduced type of s2 is



          std::set<std::array<int>::iterator>


          The declaration of s2 is equivalent to



          std::set<std::array<int>::iterator> s2 a.begin(), a.end();


          Therefore, s2 is a set of iterators that consists of two elements: a.begin() and a.end(). In your case, std::array<int>::iterator is probably int*, and a.begin() and a.end() happen to be serialized as 0x7ffecf9d12e0 and 0x7ffecf9d12f0, respectively.




          For s3, overload resolution is performed as if in



          __hypothetical __hyp(a.begin(), a.end()); // parentheses


          That's direct-initialization, and is under the scope of [pver.match.ctor]. The initializer_list constructor is irrelevant, and the Constructor #1 is selected instead. Function template argument deduction gives



          InputIterator = std::array<int>::iterator


          So the deduced type of s3 is



          set<iterator_traits<std::array<int>::iterator>::value_type>


          Which is set<int>. Therefore, the declaration of s3 is equivalent to



          std::set<int> s3 (a.begin(), a.end());


          s3 is a set of ints that is initialized from the range [a.begin(), a.end()) — four elements 1, 2, 3, 4, which explains the output.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 26 at 12:21

























          answered May 26 at 11:42









          L. F.L. F.

          3,3751337




          3,3751337












          • @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

            – Holt
            May 26 at 11:48


















          • @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

            – Holt
            May 26 at 11:48

















          @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

          – Holt
          May 26 at 11:48






          @MichaWiedenmann eel.is/c++draft/over.match.list and eel.is/c++draft/over.match.class.deduct

          – Holt
          May 26 at 11:48


















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56313139%2fwhy-does-using-uniform-initializer-syntax-result-in-different-behavior-to-the-o%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

          Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

          Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?