How do I check whether a reference is const?












3















I was writing a test for my iterator types and wanted to check that the reference returned by de-referencing iterators provided by begin() and cbegin() are non-const and const respectively.



I tried doing something similar to the following : -



#include <type_traits>
#include <iostream>
#include <vector>

int main() {
std::vector<int> vec{0};

std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}


But this prints 0 for both cases.



Is there a way to check if a reference is const?



I can use C++11/14/17 features.










share|improve this question

























  • Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

    – felix
    Nov 23 '18 at 10:19


















3















I was writing a test for my iterator types and wanted to check that the reference returned by de-referencing iterators provided by begin() and cbegin() are non-const and const respectively.



I tried doing something similar to the following : -



#include <type_traits>
#include <iostream>
#include <vector>

int main() {
std::vector<int> vec{0};

std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}


But this prints 0 for both cases.



Is there a way to check if a reference is const?



I can use C++11/14/17 features.










share|improve this question

























  • Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

    – felix
    Nov 23 '18 at 10:19
















3












3








3


1






I was writing a test for my iterator types and wanted to check that the reference returned by de-referencing iterators provided by begin() and cbegin() are non-const and const respectively.



I tried doing something similar to the following : -



#include <type_traits>
#include <iostream>
#include <vector>

int main() {
std::vector<int> vec{0};

std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}


But this prints 0 for both cases.



Is there a way to check if a reference is const?



I can use C++11/14/17 features.










share|improve this question
















I was writing a test for my iterator types and wanted to check that the reference returned by de-referencing iterators provided by begin() and cbegin() are non-const and const respectively.



I tried doing something similar to the following : -



#include <type_traits>
#include <iostream>
#include <vector>

int main() {
std::vector<int> vec{0};

std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}


But this prints 0 for both cases.



Is there a way to check if a reference is const?



I can use C++11/14/17 features.







c++ reference iterator const typetraits






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 10:21









einpoklum

36.5k28132261




36.5k28132261










asked Nov 23 '18 at 10:07









FlauFlau

90611329




90611329













  • Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

    – felix
    Nov 23 '18 at 10:19





















  • Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

    – felix
    Nov 23 '18 at 10:19



















Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

– felix
Nov 23 '18 at 10:19







Reference can never be const-qualified. Only the type to which a reference is referred can be const-qualified. std::is_const_v<std::remove_reference_t<T>>.

– felix
Nov 23 '18 at 10:19














4 Answers
4






active

oldest

votes


















4














Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:



std::is_const_v<std::remove_reference_t<decltype(*it)>>





share|improve this answer



















  • 1





    It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

    – YSC
    Nov 23 '18 at 10:22





















4














*it will be a reference rather than the referenced type (int& or const int& rather than int or const int in your case). So, you need to remove the reference:



#include <iostream>
#include <type_traits>
#include <vector>

int main() {
std::vector<int> vec{0};

for(auto it=vec.begin(); it!=vec.end(); ++it) {
std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}

for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}
}


This produces:



0
1





share|improve this answer































    2














    is_const always returns false for references. Instead, do:



    std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
    std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true





    share|improve this answer
























    • Is is_const_v preferable over is_const ?

      – Flau
      Nov 23 '18 at 10:24






    • 1





      @Flau it's just shorter. Drawback is that it requires C++17.

      – eerorika
      Nov 23 '18 at 10:25











    • @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

      – Acorn
      Nov 23 '18 at 10:25








    • 1





      Ah I see, I missed that difference - thanks.

      – Flau
      Nov 23 '18 at 10:26



















    1














    You can check the notes on document here:
    https://en.cppreference.com/w/cpp/types/is_const




    • Notes



    If T is a reference type then is_const::value is always false. The
    proper way to check a potentially-reference type for const-ness is to
    remove the reference: is_const::type>.




    for(auto it=vec.begin(); it!=vec.end(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
    }

    for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
    }





    share|improve this answer


























    • @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

      – yelliver
      Nov 23 '18 at 10:30












    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%2f53444574%2fhow-do-i-check-whether-a-reference-is-const%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:



    std::is_const_v<std::remove_reference_t<decltype(*it)>>





    share|improve this answer



















    • 1





      It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

      – YSC
      Nov 23 '18 at 10:22


















    4














    Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:



    std::is_const_v<std::remove_reference_t<decltype(*it)>>





    share|improve this answer



















    • 1





      It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

      – YSC
      Nov 23 '18 at 10:22
















    4












    4








    4







    Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:



    std::is_const_v<std::remove_reference_t<decltype(*it)>>





    share|improve this answer













    Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:



    std::is_const_v<std::remove_reference_t<decltype(*it)>>






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 10:18









    eerorikaeerorika

    88.3k663134




    88.3k663134








    • 1





      It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

      – YSC
      Nov 23 '18 at 10:22
















    • 1





      It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

      – YSC
      Nov 23 '18 at 10:22










    1




    1





    It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

    – YSC
    Nov 23 '18 at 10:22







    It calls for the definition of template<class T> constexpr bool is_const_ref_v = std::is_const_v<std::remove_reference_t<T>>;.

    – YSC
    Nov 23 '18 at 10:22















    4














    *it will be a reference rather than the referenced type (int& or const int& rather than int or const int in your case). So, you need to remove the reference:



    #include <iostream>
    #include <type_traits>
    #include <vector>

    int main() {
    std::vector<int> vec{0};

    for(auto it=vec.begin(); it!=vec.end(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
    }

    for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
    }
    }


    This produces:



    0
    1





    share|improve this answer




























      4














      *it will be a reference rather than the referenced type (int& or const int& rather than int or const int in your case). So, you need to remove the reference:



      #include <iostream>
      #include <type_traits>
      #include <vector>

      int main() {
      std::vector<int> vec{0};

      for(auto it=vec.begin(); it!=vec.end(); ++it) {
      std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
      }

      for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
      std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
      }
      }


      This produces:



      0
      1





      share|improve this answer


























        4












        4








        4







        *it will be a reference rather than the referenced type (int& or const int& rather than int or const int in your case). So, you need to remove the reference:



        #include <iostream>
        #include <type_traits>
        #include <vector>

        int main() {
        std::vector<int> vec{0};

        for(auto it=vec.begin(); it!=vec.end(); ++it) {
        std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
        }

        for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
        std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
        }
        }


        This produces:



        0
        1





        share|improve this answer













        *it will be a reference rather than the referenced type (int& or const int& rather than int or const int in your case). So, you need to remove the reference:



        #include <iostream>
        #include <type_traits>
        #include <vector>

        int main() {
        std::vector<int> vec{0};

        for(auto it=vec.begin(); it!=vec.end(); ++it) {
        std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
        }

        for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
        std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
        }
        }


        This produces:



        0
        1






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 10:19









        einpoklumeinpoklum

        36.5k28132261




        36.5k28132261























            2














            is_const always returns false for references. Instead, do:



            std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
            std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true





            share|improve this answer
























            • Is is_const_v preferable over is_const ?

              – Flau
              Nov 23 '18 at 10:24






            • 1





              @Flau it's just shorter. Drawback is that it requires C++17.

              – eerorika
              Nov 23 '18 at 10:25











            • @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

              – Acorn
              Nov 23 '18 at 10:25








            • 1





              Ah I see, I missed that difference - thanks.

              – Flau
              Nov 23 '18 at 10:26
















            2














            is_const always returns false for references. Instead, do:



            std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
            std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true





            share|improve this answer
























            • Is is_const_v preferable over is_const ?

              – Flau
              Nov 23 '18 at 10:24






            • 1





              @Flau it's just shorter. Drawback is that it requires C++17.

              – eerorika
              Nov 23 '18 at 10:25











            • @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

              – Acorn
              Nov 23 '18 at 10:25








            • 1





              Ah I see, I missed that difference - thanks.

              – Flau
              Nov 23 '18 at 10:26














            2












            2








            2







            is_const always returns false for references. Instead, do:



            std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
            std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true





            share|improve this answer













            is_const always returns false for references. Instead, do:



            std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
            std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 23 '18 at 10:20









            AcornAcorn

            5,91511339




            5,91511339













            • Is is_const_v preferable over is_const ?

              – Flau
              Nov 23 '18 at 10:24






            • 1





              @Flau it's just shorter. Drawback is that it requires C++17.

              – eerorika
              Nov 23 '18 at 10:25











            • @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

              – Acorn
              Nov 23 '18 at 10:25








            • 1





              Ah I see, I missed that difference - thanks.

              – Flau
              Nov 23 '18 at 10:26



















            • Is is_const_v preferable over is_const ?

              – Flau
              Nov 23 '18 at 10:24






            • 1





              @Flau it's just shorter. Drawback is that it requires C++17.

              – eerorika
              Nov 23 '18 at 10:25











            • @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

              – Acorn
              Nov 23 '18 at 10:25








            • 1





              Ah I see, I missed that difference - thanks.

              – Flau
              Nov 23 '18 at 10:26

















            Is is_const_v preferable over is_const ?

            – Flau
            Nov 23 '18 at 10:24





            Is is_const_v preferable over is_const ?

            – Flau
            Nov 23 '18 at 10:24




            1




            1





            @Flau it's just shorter. Drawback is that it requires C++17.

            – eerorika
            Nov 23 '18 at 10:25





            @Flau it's just shorter. Drawback is that it requires C++17.

            – eerorika
            Nov 23 '18 at 10:25













            @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

            – Acorn
            Nov 23 '18 at 10:25







            @Flau _v variants are a shorthand to avoid writing ::value; the same way _t ones avoid ::type.

            – Acorn
            Nov 23 '18 at 10:25






            1




            1





            Ah I see, I missed that difference - thanks.

            – Flau
            Nov 23 '18 at 10:26





            Ah I see, I missed that difference - thanks.

            – Flau
            Nov 23 '18 at 10:26











            1














            You can check the notes on document here:
            https://en.cppreference.com/w/cpp/types/is_const




            • Notes



            If T is a reference type then is_const::value is always false. The
            proper way to check a potentially-reference type for const-ness is to
            remove the reference: is_const::type>.




            for(auto it=vec.begin(); it!=vec.end(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }

            for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }





            share|improve this answer


























            • @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

              – yelliver
              Nov 23 '18 at 10:30
















            1














            You can check the notes on document here:
            https://en.cppreference.com/w/cpp/types/is_const




            • Notes



            If T is a reference type then is_const::value is always false. The
            proper way to check a potentially-reference type for const-ness is to
            remove the reference: is_const::type>.




            for(auto it=vec.begin(); it!=vec.end(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }

            for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }





            share|improve this answer


























            • @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

              – yelliver
              Nov 23 '18 at 10:30














            1












            1








            1







            You can check the notes on document here:
            https://en.cppreference.com/w/cpp/types/is_const




            • Notes



            If T is a reference type then is_const::value is always false. The
            proper way to check a potentially-reference type for const-ness is to
            remove the reference: is_const::type>.




            for(auto it=vec.begin(); it!=vec.end(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }

            for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }





            share|improve this answer















            You can check the notes on document here:
            https://en.cppreference.com/w/cpp/types/is_const




            • Notes



            If T is a reference type then is_const::value is always false. The
            proper way to check a potentially-reference type for const-ness is to
            remove the reference: is_const::type>.




            for(auto it=vec.begin(); it!=vec.end(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }

            for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
            std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 23 '18 at 10:29

























            answered Nov 23 '18 at 10:26









            yelliveryelliver

            2,59332152




            2,59332152













            • @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

              – yelliver
              Nov 23 '18 at 10:30



















            • @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

              – yelliver
              Nov 23 '18 at 10:30

















            @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

            – yelliver
            Nov 23 '18 at 10:30





            @YSC lol, I edited my sentence, but I think instead of giving an answer, I want to give an advice for future question

            – yelliver
            Nov 23 '18 at 10:30


















            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%2f53444574%2fhow-do-i-check-whether-a-reference-is-const%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







            這個網誌中的熱門文章

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud

            Zucchini