Are std::tuple and std::tuple considered same type by std::vector?












6















I have a variable defined like this



auto drum = std::make_tuple
( std::make_tuple
( 0.3f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
)
);


I expect drum to be a tuple of tuple. (i.e. ((a, b, c))).



And I have another variable defined like this



auto base = std::make_tuple
( 0.48f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
);


which I expect to be just a tuple of three elements (i.e (a, b, c))



I also have a vector defined as follows



std::vector<std::tuple<std::tuple< float
, ExampleClass
, std::function<float (ExampleClass&)>
>>> listOfInstruments;


Now if I add drum to listOfInstruments I expect no errors.



Which was indeed the case with listOfInstruments.push_back(drum);



Where I expected an error was here listOfInstuments.push_back(base); but the code compiles just fine.



Since listOfInstruments has type 'tuple of tuples', should't adding just 'tuple' cause some error? Unless both () and (()) are considered same types by std::vector. Or am I completely wrong and there's something else at work here?



Can't seem to figure it out.










share|improve this question























  • As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

    – Caleth
    1 hour ago
















6















I have a variable defined like this



auto drum = std::make_tuple
( std::make_tuple
( 0.3f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
)
);


I expect drum to be a tuple of tuple. (i.e. ((a, b, c))).



And I have another variable defined like this



auto base = std::make_tuple
( 0.48f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
);


which I expect to be just a tuple of three elements (i.e (a, b, c))



I also have a vector defined as follows



std::vector<std::tuple<std::tuple< float
, ExampleClass
, std::function<float (ExampleClass&)>
>>> listOfInstruments;


Now if I add drum to listOfInstruments I expect no errors.



Which was indeed the case with listOfInstruments.push_back(drum);



Where I expected an error was here listOfInstuments.push_back(base); but the code compiles just fine.



Since listOfInstruments has type 'tuple of tuples', should't adding just 'tuple' cause some error? Unless both () and (()) are considered same types by std::vector. Or am I completely wrong and there's something else at work here?



Can't seem to figure it out.










share|improve this question























  • As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

    – Caleth
    1 hour ago














6












6








6








I have a variable defined like this



auto drum = std::make_tuple
( std::make_tuple
( 0.3f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
)
);


I expect drum to be a tuple of tuple. (i.e. ((a, b, c))).



And I have another variable defined like this



auto base = std::make_tuple
( 0.48f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
);


which I expect to be just a tuple of three elements (i.e (a, b, c))



I also have a vector defined as follows



std::vector<std::tuple<std::tuple< float
, ExampleClass
, std::function<float (ExampleClass&)>
>>> listOfInstruments;


Now if I add drum to listOfInstruments I expect no errors.



Which was indeed the case with listOfInstruments.push_back(drum);



Where I expected an error was here listOfInstuments.push_back(base); but the code compiles just fine.



Since listOfInstruments has type 'tuple of tuples', should't adding just 'tuple' cause some error? Unless both () and (()) are considered same types by std::vector. Or am I completely wrong and there's something else at work here?



Can't seem to figure it out.










share|improve this question














I have a variable defined like this



auto drum = std::make_tuple
( std::make_tuple
( 0.3f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
)
);


I expect drum to be a tuple of tuple. (i.e. ((a, b, c))).



And I have another variable defined like this



auto base = std::make_tuple
( 0.48f
, ExampleClass
, (ExampleClass& instance) {return instance.eGetter ();}
);


which I expect to be just a tuple of three elements (i.e (a, b, c))



I also have a vector defined as follows



std::vector<std::tuple<std::tuple< float
, ExampleClass
, std::function<float (ExampleClass&)>
>>> listOfInstruments;


Now if I add drum to listOfInstruments I expect no errors.



Which was indeed the case with listOfInstruments.push_back(drum);



Where I expected an error was here listOfInstuments.push_back(base); but the code compiles just fine.



Since listOfInstruments has type 'tuple of tuples', should't adding just 'tuple' cause some error? Unless both () and (()) are considered same types by std::vector. Or am I completely wrong and there's something else at work here?



Can't seem to figure it out.







c++ tuples






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 3 hours ago









atisatis

34619




34619













  • As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

    – Caleth
    1 hour ago



















  • As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

    – Caleth
    1 hour ago

















As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

– Caleth
1 hour ago





As an aside, I'd strongly discourage you from declaring a std::tuple of one element, and instead use the element type.

– Caleth
1 hour ago












1 Answer
1






active

oldest

votes


















14














Tuples are mostly a red herring here. The way that works is simply that push_back can perform implicit conversions on its argument, as demonstrated by the following working snippet:



#include <vector>

struct A { };

struct B {
B(A const &) { }
};

int main() {
std::vector<B> v;
v.push_back(A{});
}


Going back to tuple, we can see that it has (among others) an implicit constructor (#2 here) which takes references to the tuple's members-to-be:



tuple( const Types&... args );


This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.






share|improve this answer























    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%2f54306241%2fare-stdtuple-and-stdtuplestdtuple-considered-same-type-by-stdvector%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









    14














    Tuples are mostly a red herring here. The way that works is simply that push_back can perform implicit conversions on its argument, as demonstrated by the following working snippet:



    #include <vector>

    struct A { };

    struct B {
    B(A const &) { }
    };

    int main() {
    std::vector<B> v;
    v.push_back(A{});
    }


    Going back to tuple, we can see that it has (among others) an implicit constructor (#2 here) which takes references to the tuple's members-to-be:



    tuple( const Types&... args );


    This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.






    share|improve this answer




























      14














      Tuples are mostly a red herring here. The way that works is simply that push_back can perform implicit conversions on its argument, as demonstrated by the following working snippet:



      #include <vector>

      struct A { };

      struct B {
      B(A const &) { }
      };

      int main() {
      std::vector<B> v;
      v.push_back(A{});
      }


      Going back to tuple, we can see that it has (among others) an implicit constructor (#2 here) which takes references to the tuple's members-to-be:



      tuple( const Types&... args );


      This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.






      share|improve this answer


























        14












        14








        14







        Tuples are mostly a red herring here. The way that works is simply that push_back can perform implicit conversions on its argument, as demonstrated by the following working snippet:



        #include <vector>

        struct A { };

        struct B {
        B(A const &) { }
        };

        int main() {
        std::vector<B> v;
        v.push_back(A{});
        }


        Going back to tuple, we can see that it has (among others) an implicit constructor (#2 here) which takes references to the tuple's members-to-be:



        tuple( const Types&... args );


        This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.






        share|improve this answer













        Tuples are mostly a red herring here. The way that works is simply that push_back can perform implicit conversions on its argument, as demonstrated by the following working snippet:



        #include <vector>

        struct A { };

        struct B {
        B(A const &) { }
        };

        int main() {
        std::vector<B> v;
        v.push_back(A{});
        }


        Going back to tuple, we can see that it has (among others) an implicit constructor (#2 here) which takes references to the tuple's members-to-be:



        tuple( const Types&... args );


        This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 3 hours ago









        QuentinQuentin

        45.6k587142




        45.6k587142






























            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%2f54306241%2fare-stdtuple-and-stdtuplestdtuple-considered-same-type-by-stdvector%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

            Callistus I

            Tabula Rosettana

            How to label and detect the document text images