Subtypes of templated types (in templated functions)

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

    Subtypes of templated types (in templated functions)

    I recently told g++ (3.2) something to the effect of:

    template <class T>
    struct test{
    typedef int type;
    };

    template <class T>
    void f(){
    test<T>::type i;
    }

    To which g++ responded (in an unfriendly manner):

    test.cpp: In function 'void f()':
    test.cpp:11: warning: 'typename test<T>::type' is implicitly a
    typename
    test.cpp:11: warning: implicit typename is deprecated, please see the
    documentation for details

    Which confused me quite a lot. "test<T>::t ype" look explicit enough to
    me... it only seems to happen when both the class and the function are
    templates, and I can declare a test<T> allright, just not a
    test<T>::type. Is this a language problem? I do not have any other
    compilers so I do not know whether it could be a compiler thingy.
    Suffice to say, it annoys me, I was trying to use a std::vector's
    iterators in a templated container class that used an internal vector,
    and it just would not allow it.

    Marijn Haverbeke
  • Patrik Stellmann

    #2
    Re: Subtypes of templated types (in templated functions)

    [color=blue]
    > template <class T>
    > void f(){
    > test<T>::type i;
    > }
    >
    > To which g++ responded (in an unfriendly manner):
    >
    > test.cpp: In function 'void f()':
    > test.cpp:11: warning: 'typename test<T>::type' is implicitly a
    > typename
    > test.cpp:11: warning: implicit typename is deprecated, please see the
    > documentation for details
    >[/color]
    Just a guess but probably the compiler simply tries to tell you that you
    should write
    typename test<T>::type i;

    Comment

    • John Harrison

      #3
      Re: Subtypes of templated types (in templated functions)


      "Marijn" <marijnjh@hotma il.com> wrote in message
      news:1d55c324.0 402120207.5a05b 86@posting.goog le.com...[color=blue]
      > I recently told g++ (3.2) something to the effect of:
      >
      > template <class T>
      > struct test{
      > typedef int type;
      > };
      >
      > template <class T>
      > void f(){
      > test<T>::type i;
      > }
      >
      > To which g++ responded (in an unfriendly manner):
      >
      > test.cpp: In function 'void f()':
      > test.cpp:11: warning: 'typename test<T>::type' is implicitly a
      > typename
      > test.cpp:11: warning: implicit typename is deprecated, please see the
      > documentation for details
      >
      > Which confused me quite a lot. "test<T>::t ype" look explicit enough to
      > me... it only seems to happen when both the class and the function are
      > templates, and I can declare a test<T> allright, just not a
      > test<T>::type.[/color]

      The compiler cannot know that test<T>::type is a typename and not a static
      data member when it is compiling f(), since at that point it does not know
      the type of T, and it does not know what template specialisations of test<T>
      might exist. Or something like that, any corrections or clarifications
      welcome.
      [color=blue]
      > Is this a language problem?[/color]

      It a requirement of the language that you say

      typename test<T>::type i;

      in this situation. Its arguably a language problem since it seems this
      ambiguity (and a few others) were not appreciated when templates where added
      informally to the language, typename got added later when this became known.
      [color=blue]
      > I do not have any other
      > compilers so I do not know whether it could be a compiler thingy.
      > Suffice to say, it annoys me, I was trying to use a std::vector's
      > iterators in a templated container class that used an internal vector,
      > and it just would not allow it.[/color]

      All you have to do is add typename, in the appropriate places.
      [color=blue]
      >
      > Marijn Haverbeke[/color]

      john


      Comment

      • Christian Jaeger

        #4
        Re: Subtypes of templated types (in templated functions)

        Well, I was thought that for templates, it makes sense to explicitly
        specify, wheter something is to be considered as a type or a non-type.
        Maybe the following example is helpful:


        struct foo{
        typedef int t;
        };

        struct bar{
        static const int t=10;
        };

        int m = 10;

        template <typename T> void f(){
        T::t* m; // declaration of an int* (for foo),
        // or multiplication (for bar)
        }

        int main(){
        f<foo>();
        f<bar>();
        }

        Comment

        • Sharad Kala

          #5
          Re: Subtypes of templated types (in templated functions)


          "Marijn" <marijnjh@hotma il.com> wrote in message
          news:1d55c324.0 402120207.5a05b 86@posting.goog le.com...[color=blue]
          > I recently told g++ (3.2) something to the effect of:
          >
          > template <class T>
          > struct test{
          > typedef int type;
          > };
          >
          > template <class T>
          > void f(){
          > test<T>::type i;
          > }
          >
          > To which g++ responded (in an unfriendly manner):
          >
          > test.cpp: In function 'void f()':
          > test.cpp:11: warning: 'typename test<T>::type' is implicitly a
          > typename
          > test.cpp:11: warning: implicit typename is deprecated, please see the
          > documentation for details
          >
          > Which confused me quite a lot. "test<T>::t ype" look explicit enough to
          > me... it only seems to happen when both the class and the function are
          > templates, and I can declare a test<T> allright, just not a
          > test<T>::type. Is this a language problem? I do not have any other
          > compilers so I do not know whether it could be a compiler thingy.
          > Suffice to say, it annoys me, I was trying to use a std::vector's
          > iterators in a templated container class that used an internal vector,
          > and it just would not allow it.[/color]

          Consider test<T>::type* i;
          May be your intention was to declare i as a pointer but compiler could take it
          for a multiplication.
          Hence the need of typename is needed in case of dependent names to tell that
          what follows is a type.
          Josuttis/Vandevoorde cover dependent names etc in good detail in Part II of
          their book "C++ Templates".

          Also it's worth to read what Herb Sutter has to say in this article -


          -Sharad


          Comment

          • Marijn

            #6
            Re: Subtypes of templated types (in templated functions)

            > All you have to do is add typename, in the appropriate places.

            Ahh okay. Thanks for the clarification. I think C++ is the only
            language that keeps surprising me after 4 years of using it.

            Marijn Haverbeke

            Comment

            Working...