problem with explicit template instantiation in Visual C++ 6.0 .

Discussion in 'C++' started by C. Carbonera, Feb 4, 2004.

  1. C. Carbonera

    C. Carbonera Guest

    /*
    Hi,

    I have a problem with explicit instantiation of templates in Visual
    C++ 6.0.
    I have provided the source below. I have an example of a function
    template that produces incorrect output in the code below.

    The function
    template < typename T >
    void DummyFunctionDoesNotWork(T &o);

    Produces incorrect output. The following is the expected output:
    First Type
    Second Type

    But, instead, I obtain the following is the output:
    Second Type
    Second Type

    I have written a second function

    template < typename T >
    void DummyFunctionWorks(T &o);

    That produces the correct output.

    Could someone please test the code given below in Visual C++.NET
    and let me know if it works?

    Thanks,
    CCarbonera
    */
    #include <fstream.h>

    enum explicit_t
    {first_t=1,
    second_t=0};

    template <explicit_t t>
    struct Dummy
    {
    const char* operator()(void){ return " UNDEFINED "; };
    };

    template <>
    const char* Dummy< first_t >::eek:perator()(){ return " First Type "; }

    template <>
    const char* Dummy<second_t>::eek:perator()(){ return " Second Type "; }

    template < typename T >
    void DummyFunctionWorks(T &o)
    { cout << o() << endl; }

    template < typename T >
    void DummyFunctionDoesNotWork()
    { T o; cout << o() << endl; }

    void main(int argc, char* argv[])
    {
    cout<< "The following produces the correct output:" << endl;
    Dummy<first_t> frst;
    Dummy<second_t> scnd;
    DummyFunctionWorks < Dummy< first_t > > ( frst );
    DummyFunctionWorks < Dummy< second_t > > ( scnd );

    cout<< "The following produces the wrong output:" << endl;
    DummyFunctionDoesNotWork < Dummy < first_t > > ( );
    DummyFunctionDoesNotWork < Dummy < second_t > > ( );
    }
    C. Carbonera, Feb 4, 2004
    #1
    1. Advertising

  2. C. Carbonera

    AirPete Guest

    C. Carbonera wrote:
    > /*

    [snip]
    >
    > Could someone please test the code given below in Visual C++.NET
    > and let me know if it works?


    It work in VC++ 2003 with a few minor modifications to include the correct
    header:

    >
    > Thanks,
    > CCarbonera
    > */
    > #include <fstream.h>


    #include <fstream>
    using namespace std;

    >
    > enum explicit_t
    > {first_t=1,
    > second_t=0};
    >
    > template <explicit_t t>
    > struct Dummy
    > {
    > const char* operator()(void){ return " UNDEFINED "; };
    > };
    >
    > template <>
    > const char* Dummy< first_t >::eek:perator()(){ return " First Type "; }
    >
    > template <>
    > const char* Dummy<second_t>::eek:perator()(){ return " Second Type "; }
    >
    > template < typename T >
    > void DummyFunctionWorks(T &o)
    > { cout << o() << endl; }
    >
    > template < typename T >
    > void DummyFunctionDoesNotWork()
    > { T o; cout << o() << endl; }
    >
    > void main(int argc, char* argv[])
    > {
    > cout<< "The following produces the correct output:" << endl;
    > Dummy<first_t> frst;
    > Dummy<second_t> scnd;
    > DummyFunctionWorks < Dummy< first_t > > ( frst );
    > DummyFunctionWorks < Dummy< second_t > > ( scnd );
    >
    > cout<< "The following produces the wrong output:" << endl;
    > DummyFunctionDoesNotWork < Dummy < first_t > > ( );
    > DummyFunctionDoesNotWork < Dummy < second_t > > ( );
    > }
    AirPete, Feb 4, 2004
    #2
    1. Advertising

  3. C. Carbonera

    AirPete Guest

    [snip]
    >
    > #include <fstream>


    Sorry, this should be <iostream> , not <fstream> .

    > using namespace std;
    >

    [snip
    AirPete, Feb 4, 2004
    #3
  4. "C. Carbonera" <> wrote in message
    news:...
    > /*
    > Hi,
    >
    > I have a problem with explicit instantiation of templates in Visual
    > C++ 6.0.
    > I have provided the source below. I have an example of a function
    > template that produces incorrect output in the code below.
    >
    > The function
    > template < typename T >
    > void DummyFunctionDoesNotWork(T &o);
    >
    > Produces incorrect output. The following is the expected output:
    > First Type
    > Second Type
    >
    > But, instead, I obtain the following is the output:
    > Second Type
    > Second Type
    >
    > I have written a second function
    >
    > template < typename T >
    > void DummyFunctionWorks(T &o);
    >
    > That produces the correct output.
    >
    > Could someone please test the code given below in Visual C++.NET
    > and let me know if it works?
    >
    > Thanks,
    > CCarbonera
    > */
    > #include <fstream.h>
    >
    > enum explicit_t
    > {first_t=1,
    > second_t=0};
    >
    > template <explicit_t t>
    > struct Dummy
    > {
    > const char* operator()(void){ return " UNDEFINED "; };
    > };
    >
    > template <>
    > const char* Dummy< first_t >::eek:perator()(){ return " First Type "; }
    >
    > template <>
    > const char* Dummy<second_t>::eek:perator()(){ return " Second Type "; }
    >
    > template < typename T >
    > void DummyFunctionWorks(T &o)
    > { cout << o() << endl; }
    >
    > template < typename T >
    > void DummyFunctionDoesNotWork()
    > { T o; cout << o() << endl; }
    >
    > void main(int argc, char* argv[])
    > {
    > cout<< "The following produces the correct output:" << endl;
    > Dummy<first_t> frst;
    > Dummy<second_t> scnd;
    > DummyFunctionWorks < Dummy< first_t > > ( frst );
    > DummyFunctionWorks < Dummy< second_t > > ( scnd );
    >
    > cout<< "The following produces the wrong output:" << endl;
    > DummyFunctionDoesNotWork < Dummy < first_t > > ( );
    > DummyFunctionDoesNotWork < Dummy < second_t > > ( );
    > }


    This is a very funny bug! Have you tried reversing the last two lines?
    I get:

    First Type
    First Type

    Both calls are resolved differently, juist because they are invoked in
    a different order.

    (By the way, you are really talking about explicit specializaion, not
    explicit instantiation. Also main returns int, ... )

    Jonathan
    Jonathan Turkanis, Feb 5, 2004
    #4
  5. C. Carbonera

    C. Carbonera Guest

    "Jonathan Turkanis" <> wrote in message news:<bvsgor$vs42v$-berlin.de>...
    > "C. Carbonera" <> wrote in message
    > news:...
    > > /*
    > > Hi,
    > >
    > > I have a problem with explicit instantiation of templates in Visual
    > > C++ 6.0.
    > > I have provided the source below. I have an example of a function
    > > template that produces incorrect output in the code below.
    > >
    > > The function
    > > template < typename T >
    > > void DummyFunctionDoesNotWork(T &o);
    > >
    > > Produces incorrect output. The following is the expected output:
    > > First Type
    > > Second Type
    > >
    > > But, instead, I obtain the following is the output:
    > > Second Type
    > > Second Type
    > >
    > > I have written a second function
    > >
    > > template < typename T >
    > > void DummyFunctionWorks(T &o);
    > >
    > > That produces the correct output.
    > >
    > > Could someone please test the code given below in Visual C++.NET
    > > and let me know if it works?
    > >
    > > Thanks,
    > > CCarbonera
    > > */
    > > #include <fstream.h>
    > >
    > > enum explicit_t
    > > {first_t=1,
    > > second_t=0};
    > >
    > > template <explicit_t t>
    > > struct Dummy
    > > {
    > > const char* operator()(void){ return " UNDEFINED "; };
    > > };
    > >
    > > template <>
    > > const char* Dummy< first_t >::eek:perator()(){ return " First Type "; }
    > >
    > > template <>
    > > const char* Dummy<second_t>::eek:perator()(){ return " Second Type "; }
    > >
    > > template < typename T >
    > > void DummyFunctionWorks(T &o)
    > > { cout << o() << endl; }
    > >
    > > template < typename T >
    > > void DummyFunctionDoesNotWork()
    > > { T o; cout << o() << endl; }
    > >
    > > void main(int argc, char* argv[])
    > > {
    > > cout<< "The following produces the correct output:" << endl;
    > > Dummy<first_t> frst;
    > > Dummy<second_t> scnd;
    > > DummyFunctionWorks < Dummy< first_t > > ( frst );
    > > DummyFunctionWorks < Dummy< second_t > > ( scnd );
    > >
    > > cout<< "The following produces the wrong output:" << endl;
    > > DummyFunctionDoesNotWork < Dummy < first_t > > ( );
    > > DummyFunctionDoesNotWork < Dummy < second_t > > ( );
    > > }

    >
    > This is a very funny bug! Have you tried reversing the last two lines?
    > I get:
    >
    > First Type
    > First Type
    >
    > Both calls are resolved differently, juist because they are invoked in
    > a different order.
    >
    > (By the way, you are really talking about explicit specializaion, not
    > explicit instantiation. Also main returns int, ... )
    >
    > Jonathan


    Jonathan,

    Thank you for your feedback.

    I have one comment. The problem occurs when the functions
    void DummyFunctionDoesNotWork < Dummy < first_t > > ( ) and
    void DummyFunctionDoesNotWork < Dummy < second_t > > ( ) are
    instantiated;
    hence, I labeled the problem as an eplicit instantiation.

    There explicit specializations of the functions
    const char* Dummy< first_t >::eek:perator()() and
    const char* Dummy< second_t >::eek:perator()()
    work well as the example below illustrates.

    /*
    Please, turn on and off the compiler directive '#define WORKS' below
    to compare the results.
    */
    #include <iostream>
    using namespace std;

    enum explicit_t
    {
    first_t=1,
    second_t=0
    };

    template <explicit_t t>
    struct Dummy{ virtual const char* operator()(void){ return NULL; };
    };

    template<>
    const char* Dummy<first_t>::eek:perator()(void) { return "First
    Function"; }

    template<>
    const char* Dummy<second_t>::eek:perator()(void) { return "Second
    Function"; }

    //#define WORKS
    #ifdef WORKS
    template <typename T>
    void DummyFunction(T o = T())
    {
    cout << T()() << endl;
    }
    #else
    template <typename T>
    void DummyFunction( )
    {
    T o;
    cout << o() << endl;
    }
    #endif

    void main(void)
    {
    DummyFunction< Dummy<first_t> >();
    DummyFunction< Dummy<second_t> >();
    }
    C. Carbonera, Feb 5, 2004
    #5
    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. Fernando Cuenca
    Replies:
    4
    Views:
    2,526
    Gianni Mariani
    Sep 6, 2004
  2. Thomas Maier-Komor
    Replies:
    6
    Views:
    623
    Thomas Maier-Komor
    May 19, 2005
  3. Replies:
    1
    Views:
    573
    Salt_Peter
    Dec 25, 2006
  4. Replies:
    4
    Views:
    369
    Barry
    Jan 2, 2008
  5. Noah Roberts
    Replies:
    6
    Views:
    1,157
    Johannes Schaub (litb)
    Feb 2, 2011
Loading...

Share This Page