CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    pair vs tuple in uniform initialization

    I'm having some problems coping with this "uniform initialization"/"initialization list" example from Bjarne Stroustrup himself.

    What bothers me is that the example does not work with tuples:

    Code:
    #include <string>
    
    #include <list>
    #include <tuple>
    #include <utility>
    
    //This works: Uniform initialization, normal
    std::pair<std::string, std::string> a{"Nygaard","Simula"};
    std::tuple<std::string, std::string> b{"Richards","BCPL"};
    
    //This doesn't work, initialization lists, normal
    //std::pair<std::string, std::string> aa{{"Nygaard","Simula"}};
    //std::tuple<std::string, std::string> bb{{"Richards","BCPL"}};
    
    //This works
    std::list<std::pair<std::string, std::string>> languages_pair = {
        {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
    };
    
    //but this doesn't
    std::list<std::tuple<std::string, std::string>> languages_tuple = {
        {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
    };
    
    int main()
    { }
    I can't understand why the tuple example is not working :/

    Which constructor are the pairs using that the tuple doesn't have?
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  2. #2
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: pair vs tuple in uniform initialization

    Hi,

    the constructor tuple::tuple(P1, P2, ...PN) is explicit.

    Code:
    std::tuple<std::string, std::string> b{"Richards","BCPL"};
    Here you are explicitly calling the constructor.

    Code:
    std::list<std::tuple<std::string, std::string>> languages_tuple = {
        {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
    };
    Here you are trying to implicitly call the constructor which is not allowed.

    As opposed to that, std::pair::pair(const Type1& __Val1, const Type2& __Val2); is not explicit.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    Re: pair vs tuple in uniform initialization

    adding to treuss post, note that as in c++03 there are direct and copy intializations, in c++11 there are also direct and copy list-initializations. That is, an initialization of the form "= { ... }" requires copy-initialization semantics for all the set of braces recursively and not just the outermost one. So, in the code

    Code:
    std::list<std::tuple<std::string, std::string>> languages_tuple = { {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"} };
    the outermost braces match to list::list(initializer_list<tuple<string,string>>), and the innermost braces sets would match to a non-explicit ( because of the copy-list-initialization ) converting tuple<string,string>(?) constructor that does not exist, hence the error.
    Maybe, your question stemmed from you trying to recover the initialization mechanism through the std::list ctor only; note that from the list pov the initialization is "legal", as in the c++03 code:

    Code:
    #include <vector>
    
    std::vector<int> v1;
    std::vector<std::vector<int>> v2(v1.begin(),v1.end()); // invokes an explicit ctor
    so there would be no problem to initialize the list through an explicit converting costructor of tuple because the list initializer list ctor is equivalent to the iterator range ctor in the obvious way; the expected behavior is enforced by an ad hoc rule triggered by the copy-initialization context.

    For example, the following nearly equivalent code should ( see below ) compile

    Code:
    std::initializer_list<std::tuple<std::string, std::string>> il{
        {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
    };
    
    std::list<std::tuple<std::string, std::string>> languages_tuple = il;
    unfortunately, I've no initializer list supporting compiler at my disposal , so, I'll leave it as a conjecture ...

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: pair vs tuple in uniform initialization

    Hum... explicit multi-variable constructors...

    Thanks
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  5. #5
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: pair vs tuple in uniform initialization

    Quote Originally Posted by superbonzo View Post
    ...
    Thanks for the info. I'm getting a better hand at the notion of initializer list, and brace enclosed intialization. They can be confusing if you try to "learn by typing" rather than learn by actually reading a book. I think I get it now though.

    It was the explicit on a double argument constructor that threw me off. The example you gave didn't compile, not because of the initiaizer list, but because the compiler can't build the tuple. It's nothing a bit of explicit can't solve:

    Code:
    std::list<std::tuple<std::string, std::string>> il{
        std::tuple<std::string, std::string>{"Nygaard","Simula"},
        std::tuple<std::string, std::string>{"Richards","BCPL"},
        std::tuple<std::string, std::string>{"Ritchie","C"}
    };
    I must say that while I am a fan of the tuples, I hate the amount of text they take to write (I hate using "using"). The fact that they are explicit, and that make_tuple builds a tuple of the wrong type end up making their use (here) especially verbose.

    No a big deal, but it doesn't quite have the elegance of the first exemple
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  6. #6
    Join Date
    Oct 2008
    Posts
    1,456

    Re: pair vs tuple in uniform initialization

    Quote Originally Posted by monarch_dodra View Post
    The example you gave didn't compile
    can you post the compiler output ?

    so, in the direct-list-initialization case only the outermost braces can match an explicit constructor ... that is, inner braces are always considered copy initializations. Ok, it makes sense, but I would also have liked a way of direct-initializing in a "nested" way ...

  7. #7
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: pair vs tuple in uniform initialization

    Quote Originally Posted by superbonzo View Post
    can you post the compiler output ?
    Sorry, should have posted it right from the beginning:

    Code:
    main.cpp|error: converting to 'std::tuple<std::basic_string<char>, std::basic_string<char> >' from initializer list would use explicit constructor 'std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = const char (&)[8], _U2 = const char (&)[7], _T1 = std::basic_string<char>, _T2 = std::basic_string<char>]'|
    This is what I get in both my first example, and with your code.

    MinGW 4.6.2.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured