Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Template: Force const parameter

Template: Force const parameter

Scheduled Pinned Locked Moved Solved C++ Gurus
c++template
13 Posts 4 Posters 5.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kshegunov
    Moderators
    wrote on 26 Aug 2016, 11:38 last edited by
    #2

    I haven't tried it, but:

    template<class T>
    QList<const T *> libraryItems() const
    {
        // ...
        QList<const T *> list;
        // ...
    }
    

    ?

    Read and abide by the Qt Code of Conduct

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Joel Bodenmann
      wrote on 26 Aug 2016, 11:41 last edited by Joel Bodenmann
      #3

      The problem with that is that then the user/caller of that method has to write code like this:

      QList<const MyLibraryItem*> myLibraryItems = mimeData->libraryItems<MyLibraryItem*>();
      

      In my opinion that is just a no-go. You'd expect the two template parameters to be the same in that assignment.

      Industrial process automation software: https://simulton.com
      Embedded Graphics & GUI library: https://ugfx.io

      K 1 Reply Last reply 26 Aug 2016, 11:45
      0
      • J Joel Bodenmann
        26 Aug 2016, 11:41

        The problem with that is that then the user/caller of that method has to write code like this:

        QList<const MyLibraryItem*> myLibraryItems = mimeData->libraryItems<MyLibraryItem*>();
        

        In my opinion that is just a no-go. You'd expect the two template parameters to be the same in that assignment.

        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 26 Aug 2016, 11:45 last edited by
        #4

        @Joel-Bodenmann
        Actually:

        QList<const MyLibraryItem *> myLibraryItems = mimeData->libraryItems<MyLibraryItem>();
        

        But yes, they differ. Whether or not it's acceptable it's up to you, I know of no other way.

        PS.
        I think a fat notice in the docs should be just enough. This isn't c++11 so what's on the left can be different from what's on the right (i.e. there's no auto confusing code). It's still valid to write:

        QWidget * button = new QToolButton();
        

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on 26 Aug 2016, 19:46 last edited by Chris Kawa
          #5

          Can I force the caller of that method to only use template types/parameters (the T thing) that are const pointers?

          I'll just assume you really meant pointers to const, because const pointer would be LibraryItem* const, which is entirely different beast.

          This is one of those cases where templates come really handy. Here's a stripped down implementation:

          class LibraryMimeData
          {
          private:
              QList<const LibraryItem*> _libraryItems;
          
              // this general type will get rid of non-pointer and pointer to non-const types
              template<typename T, bool is_pointer_to_const> struct Foo {
                  static inline QList<T> convert(const QList<const LibraryItem*>& items) = delete;
              };
          
              //the specialized type will only accept pointer to const types
              template<typename T> struct Foo<T, true> {
                  static inline QList<T> convert(const QList<const LibraryItem*>& items)
                  {
                      return /* DO THE CONVERSION */;
                  }
              };
          
          public:
              //and here's a public interface
              template<typename T> QList<T> libraryItems() const {
                  return Foo<T, std::is_pointer<T>::value && std::is_const<std::remove_pointer<T>::type>::value>::convert(_libraryItems);
              }
          };
          

          This way it will work for pointer to const types and will give a lovely error about using deleted function for all others.

          K 1 Reply Last reply 27 Aug 2016, 00:42
          5
          • C Chris Kawa
            26 Aug 2016, 19:46

            Can I force the caller of that method to only use template types/parameters (the T thing) that are const pointers?

            I'll just assume you really meant pointers to const, because const pointer would be LibraryItem* const, which is entirely different beast.

            This is one of those cases where templates come really handy. Here's a stripped down implementation:

            class LibraryMimeData
            {
            private:
                QList<const LibraryItem*> _libraryItems;
            
                // this general type will get rid of non-pointer and pointer to non-const types
                template<typename T, bool is_pointer_to_const> struct Foo {
                    static inline QList<T> convert(const QList<const LibraryItem*>& items) = delete;
                };
            
                //the specialized type will only accept pointer to const types
                template<typename T> struct Foo<T, true> {
                    static inline QList<T> convert(const QList<const LibraryItem*>& items)
                    {
                        return /* DO THE CONVERSION */;
                    }
                };
            
            public:
                //and here's a public interface
                template<typename T> QList<T> libraryItems() const {
                    return Foo<T, std::is_pointer<T>::value && std::is_const<std::remove_pointer<T>::type>::value>::convert(_libraryItems);
                }
            };
            

            This way it will work for pointer to const types and will give a lovely error about using deleted function for all others.

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 27 Aug 2016, 00:42 last edited by
            #6

            Ahahah, I needed a couple of reads to get it. It's quite nifty, albeit pretty verbose.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 27 Aug 2016, 00:58 last edited by
              #7

              @kshegunov Yeah, templates usually do that when it's not you who wrote them ;) I usually steer away from them if I can but when you need to deal with type system and avoid runtime overhead they are a very flexible tool.
              The verbose part is an implementation detail. Commented well and renamed to something better than Foo can live happily in a codebase. The user facing function has a nice clean signature.

              K 1 Reply Last reply 27 Aug 2016, 01:04
              0
              • C Chris Kawa
                27 Aug 2016, 00:58

                @kshegunov Yeah, templates usually do that when it's not you who wrote them ;) I usually steer away from them if I can but when you need to deal with type system and avoid runtime overhead they are a very flexible tool.
                The verbose part is an implementation detail. Commented well and renamed to something better than Foo can live happily in a codebase. The user facing function has a nice clean signature.

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 27 Aug 2016, 01:04 last edited by kshegunov
                #8

                @Chris-Kawa said in Template: Force const parameter:

                I usually steer away from them

                Me too, which you can deduce from my simplistic answer :P
                They're just marginally better than the preprocessor ... code writing code always perplexes me, I must admit ...

                PS.
                I must also give you credit for the partial specialization trick ... never would've come up with it myself.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 27 Aug 2016, 01:16 last edited by Chris Kawa
                  #9

                  They're just marginally better than the preprocessor

                  Awww, that's hurtful to the templates :) Preprocessor is just glorified find/replace machinery. Templates are a full blown, type safe, statically checked sub-language. Combined with constexpr they really have a Death-Star-like power (with similar caveats ;) )
                  I remember when I wrote template based compile time quick sort back in the days. Sure it resulted in a 500Mb executable and crashed the compiler for input arrays larger then a dozen elements but it was constant O(1) time for any input :P
                  Sorry for offtopic. Nostalgia took me over ;)

                  1 Reply Last reply
                  1
                  • J Offline
                    J Offline
                    Joel Bodenmann
                    wrote on 27 Aug 2016, 12:01 last edited by
                    #10

                    @Chris-Kawa said in Template: Force const parameter:

                    I'll just assume you really meant pointers to const, because const pointer would be LibraryItem* const, which is entirely different beast.

                    Your assumption is correct. Sorry for using the wrong terminology. I'll blame not-getting-enough-sleep for it :p

                    @Chris-Kawa said in Template: Force const parameter:

                    Here's a stripped down implementation:

                    Oh boy... This is going to take a while (and lots of reading) for me to understand it. But I appreciate your efforts. Also, experience tells me that all code examples you write/post on this forum always just work, so huge Thank you! although I don't understand it yet :p

                    @Chris-Kawa said in Template: Force const parameter:

                    I remember when I wrote template based compile time quick sort back in the days. Sure it resulted in a 500Mb executable and crashed the compiler for input arrays larger then a dozen elements but it was constant O(1) time for any input :P

                    Is there any blog post / white paper you can link to? Sounds interesting :)

                    Industrial process automation software: https://simulton.com
                    Embedded Graphics & GUI library: https://ugfx.io

                    1 Reply Last reply
                    0
                    • C Offline
                      C Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on 27 Aug 2016, 12:22 last edited by
                      #11

                      I guess the line that need the most explaining is this one:

                      return Foo<T, std::is_pointer<T>::value && std::is_const<std::remove_pointer<T>::type>::value>::convert(_libraryItems);
                      

                      All the std magic is just a verbose way of saying "is T a pointer and does it point to a const value" so it's pretty much
                      Foo<T, true>::convert(_libraryItems) for types that qualify and
                      Foo<T, false>::convert(_libraryItems) for those that don't.

                      Foo<T, false> will call into thet deleted specialization and Foo<T, true> into the real conversion.

                      std::is_pointer<T>::value - this is true for pointers, false for others
                      std::remove_pointer<T>::type - for any given pointer type it's a typedef for the pointed to type e.g for T being int* it's int.
                      std::is_const<X>::value - this is true for const types and false for others

                      Is there any blog post / white paper you can link to? Sounds interesting :)

                      It was a class assignment over a decade ago. I'm sure the topic has a vast coverage, but I can't give you any links because it's simply useless in practice and I hadn't any interest in it after completing it.

                      1 Reply Last reply
                      1
                      • V Offline
                        V Offline
                        VRonin
                        wrote on 31 Aug 2016, 16:29 last edited by
                        #12

                        I'm definitely in the wrong section of the forum given my knowledge of the language but why wouldn't a simple static_assert work here?

                        template<class T>
                            QList<T> libraryItems() const
                            {
                        static_assert(std::is_pointer<T>::value && std::is_const<std::remove_pointer<T>::type>::value,"You can only use const pointers as template parameters");
                                QList<T> list;
                        \\ etc
                        

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        2
                        • C Offline
                          C Offline
                          Chris Kawa
                          Lifetime Qt Champion
                          wrote on 31 Aug 2016, 17:28 last edited by
                          #13

                          @VRonin said in Template: Force const parameter:

                          why wouldn't a simple static_assert work here?

                          It definitely would.

                          1 Reply Last reply
                          0

                          11/13

                          27 Aug 2016, 12:22

                          • Login

                          • Login or register to search.
                          11 out of 13
                          • First post
                            11/13
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved