Multiple inheritance/interface delegate through template function not working

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • roman.blackhammer@gmail.com

    #1

    Multiple inheritance/interface delegate through template function not working

    Any thoughts on why TPureVirtual:: VirtFun cannot call the second
    method.
    Two compilers choke on it. Actually one works, but only if not using
    an 'ISO C++ Template Parser.'
    Why would the language allow the first version, but not the second?

    Thanks.


    // -----------------------

    #include <iostream>

    class PureVirtual
    {
    public:

    virtual void VirtFun() = 0;
    };

    template <long I, class T>
    class TPureVirtual : public PureVirtual
    {
    public:

    virtual void VirtFun()
    {
    // 1.
    static_cast<T&> (*this).Done(I) ;

    // 2.
    static_cast<T&> (*this).TDone<I >();
    }
    };

    class ImplVirtual : public TPureVirtual<1, ImplVirtual>,
    public TPureVirtual<2, ImplVirtual>
    {
    public:

    void
    Done(long I)
    {
    std::cout << "ImplVirtua l<" << I << ">::Done" << std::endl;
    }

    template <long Ivoid
    TDone()
    {
    std::cout << "ImplVirtua l<" << I << ">::TDone" << std::endl;
    }
    };

    extern "C" int
    main( int argc,
    const char **argv )
    {
    ImplVirtual impl;

    TPureVirtual<1, ImplVirtual*pv1 = static_cast< TPureVirtual<1,
    ImplVirtual>* >(&impl);
    pv1->VirtFun();

    TPureVirtual<2, ImplVirtual*pv2 = static_cast< TPureVirtual<2,
    ImplVirtual>* >(&impl);
    pv2->VirtFun();

    return 0;
    }

  • Alf P. Steinbach

    #2
    Re: Multiple inheritance/interface delegate through template functionnot working

    * roman.blackhamm er@gmail.com:
    #include <iostream>
    Technically you also need to include <ostream>.

    class PureVirtual
    {
    public:
    >
    virtual void VirtFun() = 0;
    };
    >
    template <long I, class T>
    class TPureVirtual : public PureVirtual
    {
    public:
    >
    virtual void VirtFun()
    {
    // 1.
    static_cast<T&> (*this).Done(I) ;
    >
    // 2.
    static_cast<T&> (*this).TDone<I >();
    static_cast<T&> (*this).templat e TDone<I>();

    }
    };
    >
    class ImplVirtual : public TPureVirtual<1, ImplVirtual>,
    public TPureVirtual<2, ImplVirtual>
    {
    public:
    >
    void
    Done(long I)
    {
    std::cout << "ImplVirtua l<" << I << ">::Done" << std::endl;
    }
    >
    template <long Ivoid
    TDone()
    {
    std::cout << "ImplVirtua l<" << I << ">::TDone" << std::endl;
    }
    };
    >
    extern "C" int
    main( int argc,
    const char **argv )
    That is an invalid signature for 'main'.

    int main()

    or

    int main( int, char** )

    {
    ImplVirtual impl;
    >
    TPureVirtual<1, ImplVirtual*pv1 = static_cast< TPureVirtual<1,
    ImplVirtual>* >(&impl);
    pv1->VirtFun();
    >
    TPureVirtual<2, ImplVirtual*pv2 = static_cast< TPureVirtual<2,
    ImplVirtual>* >(&impl);
    pv2->VirtFun();
    >
    return 0;
    'return 0' not necessary in 'main'.
    }
    Hth.,

    - Alf

    Comment

    • roman.blackhammer@gmail.com

      #3
      Re: Multiple inheritance/interface delegate through template function not working

      Thanks a million. I've never seen that syntax before, any thoughts on
      where you picked it up?

      Comment

      • Kai-Uwe Bux

        #4
        Re: Multiple inheritance/interface delegate through template function not working

        roman.blackhamm er@gmail.com wrote:
        #include <iostream>
        >
        class PureVirtual
        {
        public:
        >
        virtual void VirtFun() = 0;
        };
        >
        template <long I, class T>
        class TPureVirtual : public PureVirtual
        {
        public:
        >
        virtual void VirtFun()
        {
        // 1.
        static_cast<T&> (*this).Done(I) ;
        >
        // 2.
        static_cast<T&> (*this).TDone<I >();
        Try:

        static_cast<T&> (*this).T::temp late TDone<I>();

        The compiler does not think that TDone is a template. Thus, it tries hard to
        compare a member function to an int, which does not work.

        }
        };
        >
        class ImplVirtual : public TPureVirtual<1, ImplVirtual>,
        public TPureVirtual<2, ImplVirtual>
        {
        public:
        >
        void
        Done(long I)
        {
        std::cout << "ImplVirtua l<" << I << ">::Done" << std::endl;
        }
        >
        template <long Ivoid
        TDone()
        {
        std::cout << "ImplVirtua l<" << I << ">::TDone" << std::endl;
        }
        };
        >
        extern "C" int
        main( int           argc,
        const char    **argv )
        {
        ImplVirtual impl;
        >
        TPureVirtual<1, ImplVirtual*pv1 = static_cast< TPureVirtual<1,
        ImplVirtual>* >(&impl);
        pv1->VirtFun();
        >
        TPureVirtual<2, ImplVirtual*pv2 = static_cast< TPureVirtual<2,
        ImplVirtual>* >(&impl);
        pv2->VirtFun();
        >
        return 0;
        }
        Best

        Kai-Uwe Bux

        Comment

        • Robert Bauck Hamar

          #5
          Re: Multiple inheritance/interface delegate through template function not working

          roman.blackhamm er@gmail.com wrote:
          Thanks a million. I've never seen that syntax before, any thoughts on
          where you picked it up?
          A good C++ book. Bjarne Stroustrup briefly touches the subject in "The C++
          Programming Language" in section C.13.6. "C++ Templates: The Complete
          Guide" by Vandevoorde and Josuttis dives deeper into the subject.

          The key is this:
          When parsing VirtFun, the compiler doesn't know what T is. Therefore, any
          member of T is implicitly taken to be a nontemplate (and a nontype for
          T::member) unless othervise stated. This means that the compiler assumes

          static_cast<T&> (*this).TDone

          is an object. The next symbol, <, is therefore assumed to be the less than
          operator. To make the compiler think othervise, use

          static_cast<T*> (this)->template TDone<...>

          or

          static_cast<T&> (*this).templat e TDone<...>

          as Alf said.

          This syntax must also be applied to member access to templates of which T is
          a template parameter.

          --
          rbh

          Comment

          • BobR

            #6
            Re: Multiple inheritance/interface delegate through template functionnot working


            Alf P. Steinbach <alfps@start.no wrote in message...
            * roman.blackhamm er@gmail.com:
            >
            extern "C" int main( int argc, const char **argv )
            >
            That is an invalid signature for 'main'.
            >
            int main()
            or
            int main( int, char** )
            >
            { [snip]

            return 0;
            >
            'return 0' not necessary in 'main'.
            Of course, but I think it dignifies it's death. <G>
            And, on (old) compilers that accept 'void main()', is the 'return 0;'
            guaranteed?
            >
            }
            --
            Bob R
            POVrookie


            Comment

            • Marcus Kwok

              #7
              Re: Multiple inheritance/interface delegate through template functionnot working

              BobR <removeBadBobR@ worldnet.att.ne twrote:
              And, on (old) compilers that accept 'void main()', is the 'return 0;'
              guaranteed?
              I think that since void main() is non-standard, then the C++ Standard
              cannot guarantee anything about it. However, the compiler
              implementation may provide its own guarantee to make sure it does The
              Right Thing(tm) (for that platform).

              --
              Marcus Kwok
              Replace 'invalid' with 'net' to reply

              Comment

              • James Kanze

                #8
                Re: Multiple inheritance/interface delegate through template functionnot working

                On Jul 2, 4:51 pm, ricec...@gehenn om.invalid (Marcus Kwok) wrote:
                BobR <removeBadB...@ worldnet.att.ne twrote:
                And, on (old) compilers that accept 'void main()', is the 'return 0;'
                guaranteed?
                I think that since void main() is non-standard, then the C++ Standard
                cannot guarantee anything about it.
                The standard requires a diagnostic. A standard conformant
                compiler is required to issue at least a warning if void main is
                used. (Many will issue an error, and fail to compile the
                program.)
                However, the compiler
                implementation may provide its own guarantee to make sure it does The
                Right Thing(tm) (for that platform).
                Of course, regardless of what the compiler might or might not
                do, clean programming still requires the "return 0". Say what
                you mean, and mean what you say---if the function definition
                says the function returns an int, you return an int.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                Working...