add_const or remove_const based on another type











up vote
5
down vote

favorite












Here is a type trait which - I feel - could fit in std next to std::add_const and std::remove_const:



#include <type_traits>

template <typename T>
struct set_constness_of {
template <typename U>
struct by {
using type = typename std::conditional<
std::is_const<U>::value,
typename std::add_const<T>::type,
typename std::remove_const<T>::type
>::type;
};
};


Note this is intentionally C++11 to minimize requirements for using it. One can obviously define set_constness_of_t in which by is a type rather than a struct with a type.



I've also written a tiny sample program (coliru.com) to ensure it runs, at least for some cases.



/* the above definition of set_constness_of goes here (paste it) */
#inlcude <iostream>

struct foo {
void m() { std::cout << "Non-constn"; }
void m() const { std::cout << "Constn"; }
};

template <class T> void call_m() { T().m(); }

int main() {
call_m<foo>();
using bar = const int;
call_m< set_constness_of<foo>::by<bar>::type >();
}


Questions:




  • Is this correctly defined for all cases?

  • What do you think about placing the second template parameter as an inner struct's template param, rather than having two template parameters on the outer struct?

  • What do you think about the choice of naming?


Other comments are welcome.










share|improve this question




























    up vote
    5
    down vote

    favorite












    Here is a type trait which - I feel - could fit in std next to std::add_const and std::remove_const:



    #include <type_traits>

    template <typename T>
    struct set_constness_of {
    template <typename U>
    struct by {
    using type = typename std::conditional<
    std::is_const<U>::value,
    typename std::add_const<T>::type,
    typename std::remove_const<T>::type
    >::type;
    };
    };


    Note this is intentionally C++11 to minimize requirements for using it. One can obviously define set_constness_of_t in which by is a type rather than a struct with a type.



    I've also written a tiny sample program (coliru.com) to ensure it runs, at least for some cases.



    /* the above definition of set_constness_of goes here (paste it) */
    #inlcude <iostream>

    struct foo {
    void m() { std::cout << "Non-constn"; }
    void m() const { std::cout << "Constn"; }
    };

    template <class T> void call_m() { T().m(); }

    int main() {
    call_m<foo>();
    using bar = const int;
    call_m< set_constness_of<foo>::by<bar>::type >();
    }


    Questions:




    • Is this correctly defined for all cases?

    • What do you think about placing the second template parameter as an inner struct's template param, rather than having two template parameters on the outer struct?

    • What do you think about the choice of naming?


    Other comments are welcome.










    share|improve this question


























      up vote
      5
      down vote

      favorite









      up vote
      5
      down vote

      favorite











      Here is a type trait which - I feel - could fit in std next to std::add_const and std::remove_const:



      #include <type_traits>

      template <typename T>
      struct set_constness_of {
      template <typename U>
      struct by {
      using type = typename std::conditional<
      std::is_const<U>::value,
      typename std::add_const<T>::type,
      typename std::remove_const<T>::type
      >::type;
      };
      };


      Note this is intentionally C++11 to minimize requirements for using it. One can obviously define set_constness_of_t in which by is a type rather than a struct with a type.



      I've also written a tiny sample program (coliru.com) to ensure it runs, at least for some cases.



      /* the above definition of set_constness_of goes here (paste it) */
      #inlcude <iostream>

      struct foo {
      void m() { std::cout << "Non-constn"; }
      void m() const { std::cout << "Constn"; }
      };

      template <class T> void call_m() { T().m(); }

      int main() {
      call_m<foo>();
      using bar = const int;
      call_m< set_constness_of<foo>::by<bar>::type >();
      }


      Questions:




      • Is this correctly defined for all cases?

      • What do you think about placing the second template parameter as an inner struct's template param, rather than having two template parameters on the outer struct?

      • What do you think about the choice of naming?


      Other comments are welcome.










      share|improve this question















      Here is a type trait which - I feel - could fit in std next to std::add_const and std::remove_const:



      #include <type_traits>

      template <typename T>
      struct set_constness_of {
      template <typename U>
      struct by {
      using type = typename std::conditional<
      std::is_const<U>::value,
      typename std::add_const<T>::type,
      typename std::remove_const<T>::type
      >::type;
      };
      };


      Note this is intentionally C++11 to minimize requirements for using it. One can obviously define set_constness_of_t in which by is a type rather than a struct with a type.



      I've also written a tiny sample program (coliru.com) to ensure it runs, at least for some cases.



      /* the above definition of set_constness_of goes here (paste it) */
      #inlcude <iostream>

      struct foo {
      void m() { std::cout << "Non-constn"; }
      void m() const { std::cout << "Constn"; }
      };

      template <class T> void call_m() { T().m(); }

      int main() {
      call_m<foo>();
      using bar = const int;
      call_m< set_constness_of<foo>::by<bar>::type >();
      }


      Questions:




      • Is this correctly defined for all cases?

      • What do you think about placing the second template parameter as an inner struct's template param, rather than having two template parameters on the outer struct?

      • What do you think about the choice of naming?


      Other comments are welcome.







      c++ template type-safety casting constants






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 9 hours ago

























      asked 21 hours ago









      einpoklum

      1,096417




      1,096417






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote













          I don't see any obvious omissions or bugs.



          The naming and inner struct are neatly expressive (and remind me of some testing frameworks' precondition/assertion chaining). It's not something that's done by the standard library, but I don't think it should be hugely controversial.



          I might go with a naming like copy_const<foo>::from<bar> - or perhaps even the other way around: copy_const<bar>::to<foo>. Or even both! (Actually, I now wish std::is_assignable worked like that - it would be easier to remember which parameter is which!)



          None of the above is a concrete suggestion - intended merely as food for thought!






          share|improve this answer























          • If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
            – Calak
            12 hours ago












          • copy_const sounds like "copy constructor"...
            – einpoklum
            9 hours ago










          • @Calak: See my answer.
            – einpoklum
            9 hours ago


















          up vote
          2
          down vote













          Following @Calak's comment, I'm now thinking of the following change of order of the template parameters:



          #include <type_traits>

          template <typename U>
          struct constness_of {
          enum { value = std::is_const<U>::value };
          template <typename T>
          struct applied_to {
          using type = typename std::conditional<
          value,
          typename std::add_const<T>::type,
          typename std::remove_const<T>::type
          >::type;
          };
          #if __cplusplus >= 201402L
          template <typename U>
          using applied_to_t = typename applied_to<U>::type;
          #endif
          };


          Which would be used as follows:



          if (constness_of<bar>::value) { std::cout << "bar is const!n"; }


          and:



          using altered_foo = constness_of<bar>::applied_to<foo>::type;
          using altered_foo_2 = constness_of<bar>::applied_to_t<foo>;





          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            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: "196"
            };
            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',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            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%2fcodereview.stackexchange.com%2fquestions%2f208121%2fadd-const-or-remove-const-based-on-another-type%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote













            I don't see any obvious omissions or bugs.



            The naming and inner struct are neatly expressive (and remind me of some testing frameworks' precondition/assertion chaining). It's not something that's done by the standard library, but I don't think it should be hugely controversial.



            I might go with a naming like copy_const<foo>::from<bar> - or perhaps even the other way around: copy_const<bar>::to<foo>. Or even both! (Actually, I now wish std::is_assignable worked like that - it would be easier to remember which parameter is which!)



            None of the above is a concrete suggestion - intended merely as food for thought!






            share|improve this answer























            • If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
              – Calak
              12 hours ago












            • copy_const sounds like "copy constructor"...
              – einpoklum
              9 hours ago










            • @Calak: See my answer.
              – einpoklum
              9 hours ago















            up vote
            3
            down vote













            I don't see any obvious omissions or bugs.



            The naming and inner struct are neatly expressive (and remind me of some testing frameworks' precondition/assertion chaining). It's not something that's done by the standard library, but I don't think it should be hugely controversial.



            I might go with a naming like copy_const<foo>::from<bar> - or perhaps even the other way around: copy_const<bar>::to<foo>. Or even both! (Actually, I now wish std::is_assignable worked like that - it would be easier to remember which parameter is which!)



            None of the above is a concrete suggestion - intended merely as food for thought!






            share|improve this answer























            • If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
              – Calak
              12 hours ago












            • copy_const sounds like "copy constructor"...
              – einpoklum
              9 hours ago










            • @Calak: See my answer.
              – einpoklum
              9 hours ago













            up vote
            3
            down vote










            up vote
            3
            down vote









            I don't see any obvious omissions or bugs.



            The naming and inner struct are neatly expressive (and remind me of some testing frameworks' precondition/assertion chaining). It's not something that's done by the standard library, but I don't think it should be hugely controversial.



            I might go with a naming like copy_const<foo>::from<bar> - or perhaps even the other way around: copy_const<bar>::to<foo>. Or even both! (Actually, I now wish std::is_assignable worked like that - it would be easier to remember which parameter is which!)



            None of the above is a concrete suggestion - intended merely as food for thought!






            share|improve this answer














            I don't see any obvious omissions or bugs.



            The naming and inner struct are neatly expressive (and remind me of some testing frameworks' precondition/assertion chaining). It's not something that's done by the standard library, but I don't think it should be hugely controversial.



            I might go with a naming like copy_const<foo>::from<bar> - or perhaps even the other way around: copy_const<bar>::to<foo>. Or even both! (Actually, I now wish std::is_assignable worked like that - it would be easier to remember which parameter is which!)



            None of the above is a concrete suggestion - intended merely as food for thought!







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 12 hours ago

























            answered 12 hours ago









            Toby Speight

            22.2k536109




            22.2k536109












            • If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
              – Calak
              12 hours ago












            • copy_const sounds like "copy constructor"...
              – einpoklum
              9 hours ago










            • @Calak: See my answer.
              – einpoklum
              9 hours ago


















            • If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
              – Calak
              12 hours ago












            • copy_const sounds like "copy constructor"...
              – einpoklum
              9 hours ago










            • @Calak: See my answer.
              – einpoklum
              9 hours ago
















            If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
            – Calak
            12 hours ago






            If find the second version very fluent! Or maybe something like constness_from<foo>::to<bar>. There's a lot of valid option. A strawpoll might be nice :p
            – Calak
            12 hours ago














            copy_const sounds like "copy constructor"...
            – einpoklum
            9 hours ago




            copy_const sounds like "copy constructor"...
            – einpoklum
            9 hours ago












            @Calak: See my answer.
            – einpoklum
            9 hours ago




            @Calak: See my answer.
            – einpoklum
            9 hours ago












            up vote
            2
            down vote













            Following @Calak's comment, I'm now thinking of the following change of order of the template parameters:



            #include <type_traits>

            template <typename U>
            struct constness_of {
            enum { value = std::is_const<U>::value };
            template <typename T>
            struct applied_to {
            using type = typename std::conditional<
            value,
            typename std::add_const<T>::type,
            typename std::remove_const<T>::type
            >::type;
            };
            #if __cplusplus >= 201402L
            template <typename U>
            using applied_to_t = typename applied_to<U>::type;
            #endif
            };


            Which would be used as follows:



            if (constness_of<bar>::value) { std::cout << "bar is const!n"; }


            and:



            using altered_foo = constness_of<bar>::applied_to<foo>::type;
            using altered_foo_2 = constness_of<bar>::applied_to_t<foo>;





            share|improve this answer

























              up vote
              2
              down vote













              Following @Calak's comment, I'm now thinking of the following change of order of the template parameters:



              #include <type_traits>

              template <typename U>
              struct constness_of {
              enum { value = std::is_const<U>::value };
              template <typename T>
              struct applied_to {
              using type = typename std::conditional<
              value,
              typename std::add_const<T>::type,
              typename std::remove_const<T>::type
              >::type;
              };
              #if __cplusplus >= 201402L
              template <typename U>
              using applied_to_t = typename applied_to<U>::type;
              #endif
              };


              Which would be used as follows:



              if (constness_of<bar>::value) { std::cout << "bar is const!n"; }


              and:



              using altered_foo = constness_of<bar>::applied_to<foo>::type;
              using altered_foo_2 = constness_of<bar>::applied_to_t<foo>;





              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                Following @Calak's comment, I'm now thinking of the following change of order of the template parameters:



                #include <type_traits>

                template <typename U>
                struct constness_of {
                enum { value = std::is_const<U>::value };
                template <typename T>
                struct applied_to {
                using type = typename std::conditional<
                value,
                typename std::add_const<T>::type,
                typename std::remove_const<T>::type
                >::type;
                };
                #if __cplusplus >= 201402L
                template <typename U>
                using applied_to_t = typename applied_to<U>::type;
                #endif
                };


                Which would be used as follows:



                if (constness_of<bar>::value) { std::cout << "bar is const!n"; }


                and:



                using altered_foo = constness_of<bar>::applied_to<foo>::type;
                using altered_foo_2 = constness_of<bar>::applied_to_t<foo>;





                share|improve this answer












                Following @Calak's comment, I'm now thinking of the following change of order of the template parameters:



                #include <type_traits>

                template <typename U>
                struct constness_of {
                enum { value = std::is_const<U>::value };
                template <typename T>
                struct applied_to {
                using type = typename std::conditional<
                value,
                typename std::add_const<T>::type,
                typename std::remove_const<T>::type
                >::type;
                };
                #if __cplusplus >= 201402L
                template <typename U>
                using applied_to_t = typename applied_to<U>::type;
                #endif
                };


                Which would be used as follows:



                if (constness_of<bar>::value) { std::cout << "bar is const!n"; }


                and:



                using altered_foo = constness_of<bar>::applied_to<foo>::type;
                using altered_foo_2 = constness_of<bar>::applied_to_t<foo>;






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 9 hours ago









                einpoklum

                1,096417




                1,096417






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208121%2fadd-const-or-remove-const-based-on-another-type%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

                    Costa Masnaga

                    Fotorealismo

                    Sidney Franklin