Cannot invoke a templated ctor

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

    Cannot invoke a templated ctor

    The following program produces error at the definition of ``b''. However it
    compiles fine the second (supposedly equivalent) form of the templated
    constructor. Why the two alternatives aren't equivalent ?

    template<class Obj>
    struct ptr_to_member
    {
    typedef void (Obj::* type) ();
    };

    struct A
    {
    A (void (*fn) ())
    {
    }

    #if 1
    template<class Obj>
    A (typename ptr_to_member <Obj>::type fn)
    {
    }
    #else
    template<class Obj>
    A (void (Obj::* fn) ())
    {
    }
    #endif
    };

    void foo ()
    {
    }

    struct bar
    {
    void baz ()
    {
    }
    };

    A a (foo);

    A b (&bar::baz);
  • David B. Held

    #2
    Re: Cannot invoke a templated ctor

    "Momchil Velikov" <velco@fadata.b g> wrote in message
    news:87bded37.0 309230014.7b71f b0c@posting.goo gle.com...[color=blue]
    > [...]
    > template<class Obj>
    > A (typename ptr_to_member <Obj>::type fn)
    > {
    > }[/color]

    This is a non-deducible context.
    [color=blue]
    > template<class Obj>
    > A (void (Obj::* fn) ())
    > {
    > }[/color]

    This context is deducible.

    Basically, if the compiler has to instantiate a type to match a
    template parameter, then the context is non-deducible (the
    compiler is too lazy to do the instantiation, since it could
    become arbitrarily complex, and probably lead to weird
    recursions in some cases).

    Dave


    Comment

    • Chris Theis

      #3
      Re: Cannot invoke a templated ctor


      "David B. Held" <dheld@codelogi cconsulting.com > wrote in message
      news:bkp4t7$a6l $1@news.astound .net...[color=blue]
      > "Momchil Velikov" <velco@fadata.b g> wrote in message
      > news:87bded37.0 309230014.7b71f b0c@posting.goo gle.com...[color=green]
      > > [...]
      > > template<class Obj>
      > > A (typename ptr_to_member <Obj>::type fn)
      > > {
      > > }[/color]
      >
      > This is a non-deducible context.
      >[color=green]
      > > template<class Obj>
      > > A (void (Obj::* fn) ())
      > > {
      > > }[/color]
      >
      > This context is deducible.
      >
      > Basically, if the compiler has to instantiate a type to match a
      > template parameter, then the context is non-deducible (the
      > compiler is too lazy to do the instantiation, since it could
      > become arbitrarily complex, and probably lead to weird
      > recursions in some cases).
      >
      > Dave
      >[/color]

      [Just a comment]
      Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very standard
      compliant compiler in terms of templates, manages to deduce the context.

      Chris


      Comment

      • David B. Held

        #4
        Re: Cannot invoke a templated ctor

        "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message
        news:bkpcn5$k21 $1@sunnews.cern .ch...[color=blue]
        > [...]
        > [Just a comment]
        > Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very
        > standard compliant compiler in terms of templates, manages to
        > deduce the context.[/color]

        Interesting. Please try this code on it:

        template <typename T>
        struct identity
        {
        typedef T type;
        };

        template <typename T>
        void foo(typename identity<T>::ty pe)
        {
        }

        int main()
        {
        int i;
        foo(i);
        }

        Comeau online gives:

        "ComeauTest .c", line 15: error: no instance of function template "foo"
        matches the argument list
        The argument types that you used are: (int)
        foo(i);
        ^

        Note that the identity metafunction is often used explicitly to
        suppress deduction, so VC6 is truly broken indeed if it performs
        the deduction anyway (but I have a suspicion that it doesn't,
        and something else is going on with your test code).

        Dave


        Comment

        • Chris Theis

          #5
          Re: Cannot invoke a templated ctor


          "David B. Held" <dheld@codelogi cconsulting.com > wrote in message
          news:bkpv7j$d9o $1@news.astound .net...[color=blue]
          > "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message
          > news:bkpcn5$k21 $1@sunnews.cern .ch...[color=green]
          > > [...]
          > > [Just a comment]
          > > Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very
          > > standard compliant compiler in terms of templates, manages to
          > > deduce the context.[/color]
          >
          > Interesting. Please try this code on it:
          >
          > template <typename T>
          > struct identity
          > {
          > typedef T type;
          > };
          >
          > template <typename T>
          > void foo(typename identity<T>::ty pe)
          > {
          > }
          >
          > int main()
          > {
          > int i;
          > foo(i);
          > }
          >
          > Comeau online gives:
          >
          > "ComeauTest .c", line 15: error: no instance of function template "foo"
          > matches the argument list
          > The argument types that you used are: (int)
          > foo(i);
          > ^[/color]

          And IMHO it's right.
          [color=blue]
          >
          > Note that the identity metafunction is often used explicitly to
          > suppress deduction, so VC6 is truly broken indeed if it performs
          > the deduction anyway (but I have a suspicion that it doesn't,
          > and something else is going on with your test code).
          >
          > Dave
          >[/color]

          VC6 compiles the code just fine. Probably I'll give it a try on VC7
          sometime.

          Chris


          Comment

          • Chris Theis

            #6
            Re: Cannot invoke a templated ctor


            "David B. Held" <dheld@codelogi cconsulting.com > wrote in message
            news:bkp4t7$a6l $1@news.astound .net...[color=blue]
            > "Momchil Velikov" <velco@fadata.b g> wrote in message
            > news:87bded37.0 309230014.7b71f b0c@posting.goo gle.com...[color=green]
            > > [...]
            > > template<class Obj>
            > > A (typename ptr_to_member <Obj>::type fn)
            > > {
            > > }[/color]
            >
            > This is a non-deducible context.
            >[color=green]
            > > template<class Obj>
            > > A (void (Obj::* fn) ())
            > > {
            > > }[/color]
            >
            > This context is deducible.
            >
            > Basically, if the compiler has to instantiate a type to match a
            > template parameter, then the context is non-deducible (the
            > compiler is too lazy to do the instantiation, since it could
            > become arbitrarily complex, and probably lead to weird
            > recursions in some cases).
            >
            > Dave
            >[/color]

            Hi Dave, can you give me the exact part of the standard for this, please.

            Regards
            Chris


            Comment

            • Shane Beasley

              #7
              Re: Cannot invoke a templated ctor

              "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message news:<bkrgaa$r2 4$1@sunnews.cer n.ch>...
              [color=blue]
              > VC6 compiles the code just fine. Probably I'll give it a try on VC7
              > sometime.[/color]

              FWIW, VC++.NET (aka VC++7) does not accept it. But since VC++6 accepts
              it, I don't know why ISO C++ shouldn't also accept it. That is, I
              figured it just happened to be difficult or impossible to do, but
              VC++6 did it.

              Sounds like a topic for comp.std.c++, actually.

              - Shane

              Comment

              • Jerry Coffin

                #8
                Re: Cannot invoke a templated ctor

                In article <2f2d78e1.03092 41538.304eaaa2@ posting.google. com>,
                sbeasley@cs.uic .edu says...

                [ ... ]
                [color=blue]
                > FWIW, VC++.NET (aka VC++7) does not accept it. But since VC++6 accepts
                > it, I don't know why ISO C++ shouldn't also accept it. That is, I
                > figured it just happened to be difficult or impossible to do, but
                > VC++6 did it.[/color]

                Off the top of my head, I don't remember exactly what you're talking
                about, but I guess it doesn't really matter. VC++ 6 simplifies the
                language to the point that quite a few ambiguities in the real language
                don't exist in its language. An ambiguity results when a particular
                expression _could_ be interpreted in one of two possible ways. When/if
                the compiler is simply limited to the point that it doesn't recognize
                one of those possibilities at all, then what should be ambiguous input
                is unambiguous for it. Making the compiler recognize the other
                possibility, however, makes the expression ambiguous.

                --
                Later,
                Jerry.

                The universe is a figment of its own imagination.

                Comment

                • David B. Held

                  #9
                  Re: Cannot invoke a templated ctor

                  "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message
                  news:bksiil$k21 $1@sunnews.cern .ch...[color=blue]
                  > [...]
                  > Hi Dave, can you give me the exact part of the standard for this,
                  > please.[/color]

                  I wish I could, by my only copy of the standard is on a dead HD,
                  so I'll have to give you the exact part of the draft standard instead:

                  14.8.2/9

                  14.8.2/10:

                  In a type which contains a nested-name-specifier, template
                  argument values cannot be deduced for template parameters
                  used within the nested-name-specifier. [Example:

                  template<int i, typename T>
                  T deduce(A<T>::X x, // T is not deduced here
                  T t, // but T is deduced here
                  B<i>::Y y); // i is not deduced here

                  I think paragraph 10 pretty much sums it up (it does for me,
                  anyway).

                  I also highly recommend the Vandevoorde/Josuttis text on
                  templates. It doesn't always make things clear, but it always
                  makes things precise, and since templates sometimes can't be
                  clear with any amount of explanation, precision is as good as
                  it gets. ;>

                  Dave


                  Comment

                  • Momchil Velikov

                    #10
                    Re: Cannot invoke a templated ctor

                    "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message news:<bksiil$k2 1$1@sunnews.cer n.ch>...[color=blue]
                    > "David B. Held" <dheld@codelogi cconsulting.com > wrote in message
                    > news:bkp4t7$a6l $1@news.astound .net...[color=green]
                    > > "Momchil Velikov" <velco@fadata.b g> wrote in message
                    > > news:87bded37.0 309230014.7b71f b0c@posting.goo gle.com...[color=darkred]
                    > > > [...]
                    > > > template<class Obj>
                    > > > A (typename ptr_to_member <Obj>::type fn)
                    > > > {
                    > > > }[/color]
                    > >
                    > > This is a non-deducible context.
                    > >[color=darkred]
                    > > > template<class Obj>
                    > > > A (void (Obj::* fn) ())
                    > > > {
                    > > > }[/color]
                    > >
                    > > This context is deducible.
                    > >[/color]
                    > Hi Dave, can you give me the exact part of the standard for this, please.[/color]

                    14.8.2.4 [#4]

                    ~velco

                    Comment

                    • Shane Beasley

                      #11
                      Re: Cannot invoke a templated ctor

                      Jerry Coffin <jcoffin@taeus. com> wrote in message news:<MPG.19dbf 842c1500f3f989b 21@news.clspco. adelphia.net>.. .
                      [color=blue]
                      > VC++ 6 simplifies the
                      > language to the point that quite a few ambiguities in the real language
                      > don't exist in its language.[/color]

                      Actually, you're right. It seems that this "trick" only works in the
                      case where the function parameter is something like

                      typename foo<T>::type

                      where foo<T>::type is dependent on T. Frankly, that is rather useless.

                      Nevermind. :)

                      - Shane

                      Comment

                      Working...