Multiple inheritance/interface delegate through template function not working

Discussion in 'C++' started by roman.blackhammer@gmail.com, Jul 1, 2007.

  1. Guest

    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 << "ImplVirtual<" << I << ">::Done" << std::endl;
    }

    template <long I> void
    TDone()
    {
    std::cout << "ImplVirtual<" << 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;
    }
     
    , Jul 1, 2007
    #1
    1. Advertising

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

    * :
    > #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).template TDone<I>();


    > }
    > };
    >
    > class ImplVirtual : public TPureVirtual<1, ImplVirtual>,
    > public TPureVirtual<2, ImplVirtual>
    > {
    > public:
    >
    > void
    > Done(long I)
    > {
    > std::cout << "ImplVirtual<" << I << ">::Done" << std::endl;
    > }
    >
    > template <long I> void
    > TDone()
    > {
    > std::cout << "ImplVirtual<" << 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
     
    Alf P. Steinbach, Jul 1, 2007
    #2
    1. Advertising

  3. Kai-Uwe Bux Guest

    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::template 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 << "ImplVirtual<" << I << ">::Done" << std::endl;
    > }
    >
    > template <long I> void
    > TDone()
    > {
    > std::cout << "ImplVirtual<" << 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
     
    Kai-Uwe Bux, Jul 1, 2007
    #3
  4. Guest

    Thanks a million. I've never seen that syntax before, any thoughts on
    where you picked it up?
     
    , Jul 1, 2007
    #4
  5. 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).template TDone<...>

    as Alf said.

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

    --
    rbh
     
    Robert Bauck Hamar, Jul 1, 2007
    #5
  6. BobR Guest

    Re: Multiple inheritance/interface delegate through template functionnot working

    Alf P. Steinbach <> wrote in message...
    > * :
    >
    > > 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
     
    BobR, Jul 1, 2007
    #6
  7. Marcus Kwok Guest

    Re: Multiple inheritance/interface delegate through template functionnot working

    BobR <> wrote:
    > 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
     
    Marcus Kwok, Jul 2, 2007
    #7
  8. James Kanze Guest

    Re: Multiple inheritance/interface delegate through template functionnot working

    On Jul 2, 4:51 pm, (Marcus Kwok) wrote:
    > BobR <> wrote:
    > > 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:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 3, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. James
    Replies:
    2
    Views:
    935
    Richard Grimes [MVP]
    Apr 30, 2004
  2. Axel Straschil
    Replies:
    6
    Views:
    378
    Axel Straschil
    Apr 11, 2005
  3. Daniel Pitts
    Replies:
    27
    Views:
    1,944
    Mike Schilling
    Feb 27, 2008
  4. twilitegxa
    Replies:
    0
    Views:
    3,665
    twilitegxa
    Oct 19, 2009
  5. lieve again

    Multiple Inheritance vs. Interface

    lieve again, Sep 20, 2012, in forum: C++
    Replies:
    29
    Views:
    845
    Pavel
    Oct 13, 2012
Loading...

Share This Page