Implicit conversion and functional operators












0















I'm studying functional operators and can't understand why code snippets like this compile:



class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};

int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}


My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.



So what am I missing?










share|improve this question


















  • 1





    The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

    – πάντα ῥεῖ
    Jan 1 at 11:26













  • Where did you gather the user defined conversion isn't going to come into play?

    – StoryTeller
    Jan 1 at 11:27











  • "and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

    – πάντα ῥεῖ
    Jan 1 at 11:32






  • 4





    Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

    – Peter
    Jan 1 at 11:33
















0















I'm studying functional operators and can't understand why code snippets like this compile:



class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};

int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}


My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.



So what am I missing?










share|improve this question


















  • 1





    The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

    – πάντα ῥεῖ
    Jan 1 at 11:26













  • Where did you gather the user defined conversion isn't going to come into play?

    – StoryTeller
    Jan 1 at 11:27











  • "and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

    – πάντα ῥεῖ
    Jan 1 at 11:32






  • 4





    Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

    – Peter
    Jan 1 at 11:33














0












0








0








I'm studying functional operators and can't understand why code snippets like this compile:



class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};

int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}


My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.



So what am I missing?










share|improve this question














I'm studying functional operators and can't understand why code snippets like this compile:



class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};

int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}


My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.



So what am I missing?







c++ implicit-conversion






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 1 at 11:24









Andrea BoccoAndrea Bocco

44913




44913








  • 1





    The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

    – πάντα ῥεῖ
    Jan 1 at 11:26













  • Where did you gather the user defined conversion isn't going to come into play?

    – StoryTeller
    Jan 1 at 11:27











  • "and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

    – πάντα ῥεῖ
    Jan 1 at 11:32






  • 4





    Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

    – Peter
    Jan 1 at 11:33














  • 1





    The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

    – πάντα ῥεῖ
    Jan 1 at 11:26













  • Where did you gather the user defined conversion isn't going to come into play?

    – StoryTeller
    Jan 1 at 11:27











  • "and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

    – πάντα ῥεῖ
    Jan 1 at 11:32






  • 4





    Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

    – Peter
    Jan 1 at 11:33








1




1





The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

– πάντα ῥεῖ
Jan 1 at 11:26







The compiler will deduce a possible conversion for minus() using the explicit cast operator of Pocket.

– πάντα ῥεῖ
Jan 1 at 11:26















Where did you gather the user defined conversion isn't going to come into play?

– StoryTeller
Jan 1 at 11:27





Where did you gather the user defined conversion isn't going to come into play?

– StoryTeller
Jan 1 at 11:27













"and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

– πάντα ῥεῖ
Jan 1 at 11:32





"and a conversion to int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?

– πάντα ῥεῖ
Jan 1 at 11:32




4




4





Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

– Peter
Jan 1 at 11:33





Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the operator int from the Pocket class - you will see that the code no longer compiles.

– Peter
Jan 1 at 11:33












1 Answer
1






active

oldest

votes


















1














The user-defined conversion function which makes the following initializations possible in your code:



Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };


will also be used by the compiler in the transform call when applying the minus to the given range :



transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());


If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.



However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.



The relevant section in the standard for this:




15.3.2 Conversion functions [class.conv.fct]

...

2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.







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%2f53995030%2fimplicit-conversion-and-functional-operators%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









    1














    The user-defined conversion function which makes the following initializations possible in your code:



    Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
    Pocket mynumbers2 = { 3, 9, 5, 0, 4 };


    will also be used by the compiler in the transform call when applying the minus to the given range :



    transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());


    If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.



    However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.



    The relevant section in the standard for this:




    15.3.2 Conversion functions [class.conv.fct]

    ...

    2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.







    share|improve this answer




























      1














      The user-defined conversion function which makes the following initializations possible in your code:



      Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
      Pocket mynumbers2 = { 3, 9, 5, 0, 4 };


      will also be used by the compiler in the transform call when applying the minus to the given range :



      transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());


      If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.



      However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.



      The relevant section in the standard for this:




      15.3.2 Conversion functions [class.conv.fct]

      ...

      2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.







      share|improve this answer


























        1












        1








        1







        The user-defined conversion function which makes the following initializations possible in your code:



        Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
        Pocket mynumbers2 = { 3, 9, 5, 0, 4 };


        will also be used by the compiler in the transform call when applying the minus to the given range :



        transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());


        If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.



        However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.



        The relevant section in the standard for this:




        15.3.2 Conversion functions [class.conv.fct]

        ...

        2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.







        share|improve this answer













        The user-defined conversion function which makes the following initializations possible in your code:



        Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
        Pocket mynumbers2 = { 3, 9, 5, 0, 4 };


        will also be used by the compiler in the transform call when applying the minus to the given range :



        transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());


        If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.



        However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.



        The relevant section in the standard for this:




        15.3.2 Conversion functions [class.conv.fct]

        ...

        2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 2 at 6:10









        P.WP.W

        16.2k31455




        16.2k31455
































            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%2f53995030%2fimplicit-conversion-and-functional-operators%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

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith