template confusion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Floogle

    #1

    template confusion

    I cannot figure out why the following program instantiates two type
    "2" instances instead of one "1" and one "2".

    Could someone plz enlighten me?

    Many thanks

    Here's the code

    -------------------------------------------------------------------------------
    #include <iostream>
    using namespace std;

    class Base
    {
    public:

    virtual int GetType()const= 0;
    };

    class Dev1 : public Base
    {
    public:

    int GetType()const{ return 1;}
    };

    class Dev2 : public Base
    {
    public:

    int GetType()const{ return 2;}
    };

    struct BaseHolder
    {
    Base* pBase;

    BaseHolder(Base * pB):pBase(pB)
    {}
    };

    template <class T>
    BaseHolder CreateABaseHold er()
    {
    return BaseHolder(new T());
    }


    int main()
    {
    BaseHolder h1 = CreateABaseHold er<Dev1>();
    BaseHolder h2 = CreateABaseHold er<Dev2>();

    cout << "\nID of base in h1 (should be == 1) = " <<
    h1.pBase->GetType();
    cout << "\nID of base in h2 (should be == 2)= " <<
    h2.pBase->GetType();

    return 0;
    }
    -------------------------------------------------------------------------
  • Stefan Näwe

    #2
    Re: template confusion

    Floogle wrote:[color=blue]
    > I cannot figure out why the following program instantiates two type
    > "2" instances instead of one "1" and one "2".
    >
    > Could someone plz enlighten me?
    >
    > Many thanks
    >
    > Here's the code
    >
    > -------------------------------------------------------------------------------
    > #include <iostream>
    > using namespace std;
    >
    > class Base
    > {
    > public:
    >
    > virtual int GetType()const= 0;
    > };
    >
    > class Dev1 : public Base
    > {
    > public:
    >
    > int GetType()const{ return 1;}
    > };
    >
    > class Dev2 : public Base
    > {
    > public:
    >
    > int GetType()const{ return 2;}
    > };
    >
    > struct BaseHolder
    > {
    > Base* pBase;
    >
    > BaseHolder(Base * pB):pBase(pB)
    > {}
    > };
    >
    > template <class T>
    > BaseHolder CreateABaseHold er()
    > {
    > return BaseHolder(new T());
    > }
    >
    >
    > int main()
    > {
    > BaseHolder h1 = CreateABaseHold er<Dev1>();
    > BaseHolder h2 = CreateABaseHold er<Dev2>();
    >
    > cout << "\nID of base in h1 (should be == 1) = " <<
    > h1.pBase->GetType();
    > cout << "\nID of base in h2 (should be == 2)= " <<
    > h2.pBase->GetType();
    >
    > return 0;
    > }
    > -------------------------------------------------------------------------[/color]

    I get this:


    $ ./baseholder

    ID of base in h1 (should be == 1) = 1
    ID of base in h2 (should be == 2) = 2


    On which planet did you compile this?

    /S
    --
    Stefan Naewe
    naewe.s_AT_atla s_DOT_de

    Comment

    • Floogle

      #3
      Re: template confusion

      On Mon, 09 Jan 2006 11:24:35 +0100, Stefan Näwe <please@nospam. net>
      wrote:
      [color=blue]
      >Floogle wrote:[color=green]
      >> I cannot figure out why the following program instantiates two type
      >> "2" instances instead of one "1" and one "2".
      >>
      >> Could someone plz enlighten me?
      >>
      >> Many thanks
      >>
      >> Here's the code
      >>
      >> -------------------------------------------------------------------------------
      >> #include <iostream>
      >> using namespace std;
      >>
      >> class Base
      >> {
      >> public:
      >>
      >> virtual int GetType()const= 0;
      >> };
      >>
      >> class Dev1 : public Base
      >> {
      >> public:
      >>
      >> int GetType()const{ return 1;}
      >> };
      >>
      >> class Dev2 : public Base
      >> {
      >> public:
      >>
      >> int GetType()const{ return 2;}
      >> };
      >>
      >> struct BaseHolder
      >> {
      >> Base* pBase;
      >>
      >> BaseHolder(Base * pB):pBase(pB)
      >> {}
      >> };
      >>
      >> template <class T>
      >> BaseHolder CreateABaseHold er()
      >> {
      >> return BaseHolder(new T());
      >> }
      >>
      >>
      >> int main()
      >> {
      >> BaseHolder h1 = CreateABaseHold er<Dev1>();
      >> BaseHolder h2 = CreateABaseHold er<Dev2>();
      >>
      >> cout << "\nID of base in h1 (should be == 1) = " <<
      >> h1.pBase->GetType();
      >> cout << "\nID of base in h2 (should be == 2)= " <<
      >> h2.pBase->GetType();
      >>
      >> return 0;
      >> }
      >> -------------------------------------------------------------------------[/color]
      >
      >I get this:
      >
      >
      >$ ./baseholder
      >
      >ID of base in h1 (should be == 1) = 1
      >ID of base in h2 (should be == 2) = 2
      >
      >
      >On which planet did you compile this?
      >
      >/S[/color]


      On planet MSVC6

      Comment

      • Ben Pope

        #4
        Re: template confusion

        Floogle wrote:[color=blue]
        > On planet MSVC6[/color]

        http://msdn.microsoft.com/vstudio/ex...c/default.aspx

        It's free!

        Ben Pope
        --
        I'm not just a number. To many, I'm known as a string...

        Comment

        • Stefan Näwe

          #5
          Re: template confusion

          Floogle wrote:[color=blue]
          > On Mon, 09 Jan 2006 11:24:35 +0100, Stefan Näwe <please@nospam. net>
          > wrote:
          >
          >[color=green]
          >>Floogle wrote:
          >>[color=darkred]
          >>>I cannot figure out why the following program instantiates two type
          >>>"2" instances instead of one "1" and one "2".
          >>>
          >>>Could someone plz enlighten me?
          >>>
          >>>Many thanks
          >>>
          >>>Here's the code
          >>>
          >>>-------------------------------------------------------------------------------
          >>>#include <iostream>
          >>>using namespace std;
          >>>
          >>>class Base
          >>>{
          >>>public:
          >>>
          >>> virtual int GetType()const= 0;
          >>>};
          >>>
          >>>class Dev1 : public Base
          >>>{
          >>>public:
          >>>
          >>> int GetType()const{ return 1;}
          >>>};
          >>>
          >>>class Dev2 : public Base
          >>>{
          >>>public:
          >>>
          >>> int GetType()const{ return 2;}
          >>>};
          >>>
          >>>struct BaseHolder
          >>>{
          >>> Base* pBase;
          >>>
          >>> BaseHolder(Base * pB):pBase(pB)
          >>> {}
          >>>};
          >>>
          >>>template <class T>
          >>>BaseHolder CreateABaseHold er()
          >>>{
          >>> return BaseHolder(new T());
          >>>}
          >>>
          >>>
          >>>int main()
          >>>{
          >>> BaseHolder h1 = CreateABaseHold er<Dev1>();
          >>> BaseHolder h2 = CreateABaseHold er<Dev2>();
          >>>
          >>> cout << "\nID of base in h1 (should be == 1) = " <<
          >>>h1.pBase->GetType();
          >>> cout << "\nID of base in h2 (should be == 2)= " <<
          >>>h2.pBase->GetType();
          >>>
          >>> return 0;
          >>>}
          >>>-------------------------------------------------------------------------[/color]
          >>
          >>I get this:
          >>
          >>
          >>$ ./baseholder
          >>
          >>ID of base in h1 (should be == 1) = 1
          >>ID of base in h2 (should be == 2) = 2
          >>
          >>
          >>On which planet did you compile this?
          >>
          >>/S[/color]
          >
          >
          >
          > On planet MSVC6[/color]

          OK.
          I initially tried that with GCC 3.4.4 from Cygwin.

          The test with MSVC gave me:

          $ ./baseholder.exe

          ID of base in h1 (should be == 1) = 2
          ID of base in h2 (should be == 2) = 2


          I'm confused, too!
          It's probably one more of those annoying MSVC stupidities...


          /S
          --
          Stefan Naewe
          naewe.s_AT_atla s_DOT_de

          Comment

          • Floogle

            #6
            Re: template confusion

            On Mon, 09 Jan 2006 11:05:13 +0000, Ben Pope
            <benpope81REMOV E@gmail.com> wrote:
            [color=blue]
            >Floogle wrote:[color=green]
            >> On planet MSVC6[/color]
            >
            >http://msdn.microsoft.com/vstudio/ex...c/default.aspx
            >
            >It's free!
            >
            >Ben Pope[/color]


            Alas, it's not that simple. It has to work using MSVC6... :o(

            Comment

            • Gernot Frisch

              #7
              Re: template confusion

              [color=blue]
              > I'm confused, too!
              > It's probably one more of those annoying MSVC stupidities...[/color]

              Lokks like a bug rather than a stupidity.


              Comment

              • Ben Pope

                #8
                Re: template confusion

                Floogle wrote:[color=blue]
                > On Mon, 09 Jan 2006 11:05:13 +0000, Ben Pope
                > <benpope81REMOV E@gmail.com> wrote:
                >[color=green]
                >> Floogle wrote:[color=darkred]
                >>> On planet MSVC6[/color]
                >> http://msdn.microsoft.com/vstudio/ex...c/default.aspx
                >>
                >> It's free!
                >>
                >> Ben Pope[/color]
                >
                >
                > Alas, it's not that simple. It has to work using MSVC6... :o([/color]

                It never is. I have an MSVC6 program, having spent the time to port it
                to MSVC2005 it now behaves "strangely" .

                With MSVC6 you are restricting your template abilities considerably...
                Perhaps you can poke around within boost code for MSVC6 workarounds.

                Good luck.

                Ben Pope
                --
                I'm not just a number. To many, I'm known as a string...

                Comment

                • Stefan Näwe

                  #9
                  Re: template confusion

                  Gernot Frisch wrote:[color=blue][color=green]
                  >>I'm confused, too!
                  >>It's probably one more of those annoying MSVC stupidities...[/color]
                  >
                  >
                  > Lokks like a bug rather than a stupidity.
                  >
                  >[/color]

                  It's a stupidity when you can get around it:

                  <----CODE---->

                  #include <iostream>
                  using namespace std;

                  class Base
                  {
                  public:
                  virtual ~Base() { }
                  virtual int GetType()const= 0;
                  };

                  class Dev1 : public Base
                  {
                  public:

                  int GetType()const{ return 1;}
                  };

                  class Dev2 : public Base
                  {
                  public:

                  int GetType()const{ return 2;}
                  };

                  struct BaseHolder
                  {
                  Base* pBase;

                  BaseHolder(Base * pB):pBase(pB)
                  {}
                  };

                  template<typena me T>
                  struct TypeHolder
                  {
                  typedef T OriginalType;
                  };

                  template <class T>
                  BaseHolder CreateABaseHold er(TypeHolder<T >)
                  {
                  return BaseHolder(new T());
                  }

                  int main()
                  {
                  BaseHolder h1 = CreateABaseHold er(TypeHolder<D ev1>());
                  BaseHolder h2 = CreateABaseHold er(TypeHolder<D ev2>());

                  cout << "\nID of base in h1 (should be == 1) = " << h1.pBase->GetType();
                  cout << "\nID of base in h2 (should be == 2) = " << h2.pBase->GetType();

                  return 0;
                  }

                  <----/CODE---->

                  /S
                  --
                  Stefan Naewe
                  naewe.s_AT_atla s_DOT_de

                  Comment

                  • Bo Persson

                    #10
                    Re: template confusion


                    "Floogle" <BananaSplits@N OSPAM.com> skrev i meddelandet
                    news:fgh4s1l5a5 t76cnmgqblfuq7p rmo7a95p6@4ax.c om...[color=blue]
                    > On Mon, 09 Jan 2006 11:05:13 +0000, Ben Pope
                    > <benpope81REMOV E@gmail.com> wrote:
                    >[color=green]
                    >>Floogle wrote:[color=darkred]
                    >>> On planet MSVC6[/color]
                    >>
                    >>http://msdn.microsoft.com/vstudio/ex...c/default.aspx
                    >>
                    >>It's free!
                    >>
                    >>Ben Pope[/color]
                    >
                    >
                    > Alas, it's not that simple. It has to work using MSVC6... :o([/color]


                    It is a known bug in VC6, that function templates that don't use the
                    template as a function parameter will confuse the linker. If you have
                    several overloads, one of them will be used (at random).

                    template <class T>
                    BaseHolder CreateABaseHold er()
                    {
                    return BaseHolder(new T());
                    }

                    doesn't work (as you have noticed).

                    The solution is to add a dummy parameter of type T, to generate a
                    different internal name.

                    template <class T>
                    BaseHolder CreateABaseHold er(const T* dummy = 0)
                    {
                    return BaseHolder(new T());
                    }

                    will work!


                    Bo Persson



                    Comment

                    Working...