What is wrong with the following program (using an empty class to choose overloaded function)?

Discussion in 'C++' started by PengYu.UT@gmail.com, Nov 2, 2005.

  1. Guest

    Hi,

    I run into error with the following program. Would you please help me?

    Best wishes,
    Peng

    struct tag1{};
    struct tag2{};

    template <typename T>
    inline void test(tag1){
    }

    template <typename T>
    inline void test(tag2){
    }

    int main(){
    test(tag1);//error with g++-3.4.4
    }
     
    , Nov 2, 2005
    #1
    1. Advertising

  2. red floyd Guest

    Re: What is wrong with the following program (using an empty classto choose overloaded function)?

    wrote:
    > Hi,
    >
    > I run into error with the following program. Would you please help me?
    >
    > Best wishes,
    > Peng
    >
    > struct tag1{};
    > struct tag2{};
    >
    > template <typename T>
    > inline void test(tag1){
    > }
    >
    > template <typename T>
    > inline void test(tag2){
    > }
    >
    > int main(){
    > test(tag1);//error with g++-3.4.4


    tag1 is not a variable, it is a type. I would guess that you're getting
    a redeclaration error.
    > }
    >
     
    red floyd, Nov 2, 2005
    #2
    1. Advertising

  3. Mike Wahler Guest

    <> wrote in message
    news:...
    > Hi,
    >
    > I run into error with the following program. Would you please help me?
    >
    > Best wishes,
    > Peng
    >
    > struct tag1{};
    > struct tag2{};
    >
    > template <typename T>
    > inline void test(tag1){
    > }
    >
    > template <typename T>
    > inline void test(tag2){
    > }
    >
    > int main(){
    > test(tag1);//error with g++-3.4.4


    The argument must be an instance of an object,
    not the name of a type. In addition, since
    'test' is a function template, and there's
    no way to deduce one, a template argument must
    be specified.

    Try:

    test<int>(tag1());

    BTW I think you're obscuring things with your templates.
    They're not needed at all.

    struct tag1{};
    struct tag2{};

    void test(tag1){
    }

    void test(tag2){
    }

    int main(){
    test(tag1());
    return 0;
    }

    I think you need to read more about templates and what
    they're for.

    -Mike
     
    Mike Wahler, Nov 2, 2005
    #3
  4. Peter_Julian Guest

    <> wrote in message
    news:...
    | Hi,
    |
    | I run into error with the following program. Would you please help me?
    |
    | Best wishes,
    | Peng
    |
    | struct tag1{};
    | struct tag2{};

    should be:

    struct Tag1{};
    struct Tag2{};

    By convention and to save a programmer from having to pop aspirin for a
    living, a capitalized name is reserved for structs and classes. So if
    you see Tag1, its a type, while tag1 might be an instance of a Tag1
    type.

    |
    | template <typename T>
    | inline void test(tag1){
    | }

    tag1 here is a type, not an instance... you don't need multiple
    definitions of the same template either. The following template can
    potentially accept any class.

    template< typename T >
    void test( T& t ) // pass_by_reference
    {
    }

    or

    template< typename T >
    void test( const T& t ) // pass_by_const_reference
    {
    // t is unmodifiable and therefore safe
    }


    |
    | template <typename T>
    | inline void test(tag2){
    | }
    above not needed...

    |
    | int main(){
    | test(tag1);//error with g++-3.4.4
    // error because tag1 was a type and test() doesn't exist.

    Tag1 tag1; // tag1 is an instance of a Tag1 type.
    Tag2 tag2;

    test< Tag1 >(tag1); // templated<> with a Tag1 type,
    // and tag1 is the object being passed
    test< Tag2 >(tag2);

    int n;
    test< int >(n); // doing it with a primitive integer, and so on...

    | }
    |

    If you really did mean to specialize the test template...then...

    template< typename T = Tag1 >
    void test( T& t )
    {
    // do this if T is Tag1
    }

    template<>
    void test<Tag2>( T& t )
    {
    // do this if T is Tag2
    }

    int main()
    {
    Tag1 tag1;
    test(tag1); // default T = Tag1

    Tag2 tag2;
    test<Tag2>(tag2); // you must tell the compiler
    }
     
    Peter_Julian, Nov 2, 2005
    #4
  5. Greg Guest

    Peter_Julian wrote:
    > <> wrote in message
    > news:...
    > | Hi,
    > |
    > | I run into error with the following program. Would you please help me?
    > |
    > | Best wishes,
    > | Peng
    > |

    ....
    >
    > If you really did mean to specialize the test template...then...
    >
    > template< typename T = Tag1 >
    > void test( T& t )
    > {
    > // do this if T is Tag1
    > }


    Only a class template can specify a default type parameter. A function
    template may not.

    > template<>
    > void test<Tag2>( T& t )
    > {
    > // do this if T is Tag2
    > }


    Since the only purpose of the function's parameter is to select the
    specialization, I think test() should be specialized for Tag2 like so:

    template <>
    void test( Tag2 t)
    {
    }

    Tag2 is an empty class - so there is no reason either to pass the
    parameter by reference or to declare it const.

    > int main()
    > {
    > Tag1 tag1;
    > test(tag1); // default T = Tag1


    No, there is no default type possible here.

    > Tag2 tag2;
    > test<Tag2>(tag2); // you must tell the compiler
    > }


    If the test function template deduced the specialized type from its
    parameter as I suggested above, then calling test( tag2) would be
    possible.

    Greg
     
    Greg, Nov 2, 2005
    #5
  6. werasm Guest

    > The argument must be an instance of an object,
    > not the name of a type.


    Yes, true - arg must be an instance of type.

    > In addition, since
    > 'test' is a function template, and there's
    > no way to deduce one, a template argument must
    > be specified.


    Hmmm, ever heard of make functions - function templates determine
    (deduce) the template parameters from the arguments passed (C++
    template p.12). For his example this may be true. How do you think
    std::min, std::max, std::make_pair can be called without explicitly
    specifying the template parameters :0.

    >
    > Try:
    >
    > test<int>(tag1());


    .... or
    test( tag1() ); //Should work to, and
    //instantiate test<tag1>, which is what he wanted.

    >
    > BTW I think you're obscuring things with your templates.
    > They're not needed at all.


    Maybe true, but trying things out to come to grips is not so bad.


    > I think you need to read more about templates and what
    > they're for.


    IMHO you may require some touching up too.

    >
    > -Mike


    Werner
     
    werasm, Nov 2, 2005
    #6
  7. werasm Guest

    Mike Wahler wrote:
    > <> wrote in message
    > news:...
    > > Hi,
    > >
    > > I run into error with the following program. Would you please help me?
    > >
    > > Best wishes,
    > > Peng
    > >
    > > struct tag1{};
    > > struct tag2{};
    > >
    > > template <typename T>
    > > inline void test(tag1){
    > > }
    > >
    > > template <typename T>
    > > inline void test(tag2){
    > > }
    > >
    > > int main(){
    > > test(tag1);//error with g++-3.4.4

    >
    > The argument must be an instance of an object,
    > not the name of a type. In addition, since
    > 'test' is a function template, and there's
    > no way to deduce one, a template argument must
    > be specified.


    Please ignore my previous msg, I read the original posting too quick. I
    took it for:

    template <typename T>
    inline void test( T )
    {
    }

    struct Tag1{};
    struct Tag2{};

    int main()
    {
    test( Tag1() );
    test( Tag2() );
    //..or test( 10 );
    }

    because this would be the more obvious thing. In this case one would
    not require test<int>( Tag1() ); //And of course it would not compile

    >
    > Try:
    >
    > test<int>(tag1());


    Yes, absolutely.

    >
    > BTW I think you're obscuring things with your templates.
    > They're not needed at all.


    Certainly, but he may be learning (fooling around to learn).

    > I think you need to read more about templates and what
    > they're for.


    He certainly does, and you don't (as I mentioned previously).

    >
    > -Mike


    Regards (and sorry),

    Werner
     
    werasm, Nov 2, 2005
    #7
    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. modemer
    Replies:
    20
    Views:
    1,367
    Howard
    Mar 22, 2005
  2. Replies:
    4
    Views:
    342
    Kristo
    May 9, 2005
  3. Replies:
    1
    Views:
    316
    Victor Bazarov
    Oct 22, 2005
  4. Jason Doucette
    Replies:
    15
    Views:
    461
    Jason Doucette
    Jul 27, 2007
  5. wkevin
    Replies:
    19
    Views:
    170
    Keith Thompson
    Feb 11, 2014
Loading...

Share This Page