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. [Solved] template compilable with MSVC and does not compile with MinGW
Forum Updated to NodeBB v4.3 + New Features

[Solved] template compilable with MSVC and does not compile with MinGW

Scheduled Pinned Locked Moved C++ Gurus
12 Posts 4 Posters 5.4k Views 1 Watching
  • 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
    koahnig
    wrote on 19 Jul 2012, 16:48 last edited by
    #1

    I am trying to compile my application using Qt with MinGW under Qt creator. The application and all its libraries compile without issues with msvc 2005. The application uses both stl and Qt while most of the containers are really in stl and Qt is for GUI and communication used.
    With MinGW I got compile errors with an extended template based on a stl map:
    @
    template < class T >
    class KaSlimContBase : public std :: map < std :: string, T >
    {
    public:
    KaSlimContBase ( );

    KaSlimContBase ( const std :: set < T > & st );
    const_iterator findName ( T & val ) const     //    <<   line 41
    {
        for ( const_iterator it = begin(); it != end(); ++it ) 
        {
            if ( it->second->getName() == val->getName() )
                return it;
        }
        return end();
    }
    void cap ( const KaSlimContBase <T> & lhs, const KaSlimContBase <T> & rhs );
    void cap ( const std :: set < T > & lhs, const KaSlimContBase <T> & rhs );
    void cap ( const KaSlimContBase <T> & lhs, const std :: set < T > & rhs );
    void print ( std :: ostream & os ) const;
    void printInfo ( std :: ostream & os, int level, int ident = 4 ) const;
    

    };
    @

    The compiler is not happy when returning a const_iterator in the marked line above.
    @
    ..\InterfaceLib/KaSlim/KaSlimContBase.h:41: error: ISO C++ forbids declaration of 'const_iterator' with no type
    ..\InterfaceLib/KaSlim/KaSlimContBase.h:41: error: expected ';' before 'findName'__
    @

    I have searched the Internet but all feedback I have found has been on when the return value of a function not specified (e.g. void, int, or more complicated std::vector<std::vector<char *> > I have found).

    For the case above I have tried:

    • std :: map :: const_iterator
    • std :: map < std :: string, T > :: const_iterator
      or more desperately
    • std :: map < std :: string, T > :: const_iterator < std :: string, T >
    • const_iterator < std :: string, T >

    Does anyone have good suggestions?

    Vote the answer(s) that helped you to solve your issue(s)

    1 Reply Last reply
    0
    • F Offline
      F Offline
      franku
      wrote on 19 Jul 2012, 17:11 last edited by
      #2

      If you want to use the the STL iterator then you want to have a look at "this":http://www.qtcentre.org/threads/40255-How-to-use-STL-in-Qt

      HTH.

      This, Jen, is the internet.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        koahnig
        wrote on 19 Jul 2012, 18:37 last edited by
        #3

        Well, the stl support is apparently available, since a very basic program using Qt and stl string does compile without adding stl stuff.

        For the code I have I would have expected that the compiler would complain for stl includes or when the map is used first a couple of lines up.

        Vote the answer(s) that helped you to solve your issue(s)

        1 Reply Last reply
        0
        • F Offline
          F Offline
          franku
          wrote on 19 Jul 2012, 20:02 last edited by
          #4

          This file: mingw\include\c++\4.4.7\bits\stl_map.h

          I found the comment:

          @// many of these are specified differently in ISO, but the following are
          // "functionally equivalent"
          ...
          typedef typename _Rep_type::const_iterator const_iterator;
          ...
          @

          Probably the implementation is not the same as msvc uses (I am no expert with STL, though).

          This, Jen, is the internet.

          1 Reply Last reply
          0
          • K Offline
            K Offline
            koahnig
            wrote on 19 Jul 2012, 20:14 last edited by
            #5

            Yes, you are right.

            It is a nested template issue and the very same typedef.

            Here is a small test with the standard Qt project example a bit furnished with stl.

            @
            #include <QtGui/QApplication>
            #include "mainwindow.h"
            #include <string>
            #include <map>

            class MyClass : public std :: map <std :: string, std ::string>
            {
            public:
            int sizeValue () const
            {
            return size();
            }
            const_iterator myBegin()
            {
            return begin();
            }
            };

            template <class T>
            class TMyClass : public std :: map <std :: string, T>
            {
            public:
            int sizeValue () const
            {
            return std::map<std::string, T>::size();
            }
            const_iterator myBegin()
            {
            return begin();
            }
            };

            int main(int argc, char *argv[])
            {
            QApplication a(argc, argv);
            MainWindow w;
            w.show();
            std :: string str;

            return a.exec&#40;&#41;;
            

            }
            @

            With line 27 the problem starts. Even so the template is not used yet. I have tried using some of the stuff from the stl include, but did not arrive at a solution.

            I decided to find another way to solve it.

            Odd that some even old ms stuff outperforms other compilers/libs. Most developers claim the other way around ;-)

            Vote the answer(s) that helped you to solve your issue(s)

            1 Reply Last reply
            0
            • G Offline
              G Offline
              giesbert
              wrote on 20 Jul 2012, 08:10 last edited by
              #6

              Hi Koahnig,

              the problem is that const_iterator is template based on the paramete T. The following code solves your problem:

              @
              // test123.cpp : Defines the entry point for the console application.
              //

              #include <string>
              #include <map>

              class MyClass : public std::map <std::string, std::string>
              {
              public:
              int sizeValue () const
              {
              return size();
              }
              const_iterator myBegin()
              {
              return begin();
              }
              };

              template <class T>
              class TMyClass : public std::map<std::string, T>
              {
              public:
              typedef map<std::string, T> _MyType;

              int sizeValue () const
              {
                  return std::map<std::string, T>::size();
              }
              _MyType::const_iterator myBegin()
              {
                  return begin();
              }
              

              };

              int main(int argc, char *argv[])
              {
              std::string str;

              MyClass a;
              TMyClass<int> b;
              
              return 0;
              

              }

              @

              Nokia Certified Qt Specialist.
              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

              1 Reply Last reply
              0
              • K Offline
                K Offline
                koahnig
                wrote on 20 Jul 2012, 08:34 last edited by
                #7

                Hi Gerolf,

                did not help. Checked your proposal and also with a slight modification.
                @
                typedef std::map<std::string, T> _MyType;
                @

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  giesbert
                  wrote on 20 Jul 2012, 09:04 last edited by
                  #8

                  Ok,

                  i looked a bit deeper, and found a solution for you:

                  @
                  #include <string>
                  #include <map>

                  class MyClass : public std::map <std::string, std::string>
                  {
                  public:
                  int sizeValue () const
                  {
                  return size();
                  }
                  const_iterator myBegin()
                  {
                  return begin();
                  }
                  };

                  template <class T>
                  class TMyClass : public std::map<std::string, T>
                  {
                  public:
                  typedef typename std::map<std::string, T> _MyType;
                  typedef typename _MyType::const_iterator const_iterator;

                  int sizeValue () const
                  {
                      return _MyType::size();
                  }
                  const_iterator myBegin()
                  {
                      return _MyType::begin();
                  }
                  

                  };

                  int main(int /argc/, char* /argv/[])
                  {
                  std::string str;

                  MyClass a;
                  TMyClass<int> b;
                  
                  return 0;
                  

                  }
                  @

                  The key was looking at the MinGW std::map code ;-)

                  This code compiled with MSVS2008SP1 and with MinGW 4.4.0

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply
                  0
                  • W Offline
                    W Offline
                    Wilk
                    wrote on 20 Jul 2012, 09:07 last edited by
                    #9

                    Hello.
                    May I ask you a stupid question: what do you want to achieve by creating a class derived from std::map? AFAIK you'd better use agregation instead of inheritence. Or just some typedef.

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      koahnig
                      wrote on 20 Jul 2012, 10:05 last edited by
                      #10

                      @Gerolf:
                      This does the trick. Thanks a lot.

                      @Wilk:
                      Initially I started out with a class extending a bit the functionality of std::map. That worked fine.
                      I realized that the same extension would be handy for other objects in that context as well. So I wrote the extended template inheriting from stl::map. Wasn't any issue for msvc at all. Worked straight away and did what I needed.
                      Just minGW was not happy about the template and required a bit of convincing ;-)
                      It is on my list for considering a redesign, but certainly not right now. There are other areas of more importance to focus on.

                      You might be right with your comment, but I do not see a way how aggregation or typedef might prevent the nested templates. Can you elaborate a bit more?

                      Vote the answer(s) that helped you to solve your issue(s)

                      1 Reply Last reply
                      0
                      • W Offline
                        W Offline
                        Wilk
                        wrote on 20 Jul 2012, 10:31 last edited by
                        #11

                        Your approach may be the only way of achieving a polymorphism, i.e. if your class is used instead of std::map in some places. I mean if you realy use that IS_A relation between your class and std::map. But if you don't use this relation you may try code like this:
                        @
                        template <class T, class TT> class C {
                        public:
                        C ();

                        TT operator[](const T &key) {
                          TT res;
                          return res;
                        }
                        

                        private:
                        std::map<T,TT> m_map;
                        };
                        @
                        Probably it's not the best or just better way, but I think its a little bit more flexible, because you may change realisation without changing any other code, while if you use inheritence you may want to use IS_A relation, so you may have some problems if you'd like to change basic realisation of your class (KaSlimContBase). (Sorry for this long sentence and mistakes, English is not my native language)

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          koahnig
                          wrote on 20 Jul 2012, 10:55 last edited by
                          #12

                          The idea was IS_A relation and to avoid repeating the same statements all over again. And certainly the debugging when the errors are repeated.
                          The encapsulation of map in my class is certainly an option, but this would require quite some replication of map access methods. So the decision was driven by my laziness ;-)

                          PS: Do not worry about long sentences. I hear it all the time that I should make shorter sentences in English. I am not a native English speaker either ;-)

                          Vote the answer(s) that helped you to solve your issue(s)

                          1 Reply Last reply
                          0

                          1/12

                          19 Jul 2012, 16:48

                          • Login

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