Template Question

This is a discussion on Template Question within the C++ Programming forums, part of the General Programming Boards category; Hello fellow coders, I am trying to create a template that behaves differently if it is give a primative type ...

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    4

    Template Question

    Hello fellow coders,

    I am trying to create a template that behaves differently
    if it is give a primative type vs a class. I should be easy
    enough but my brain seems to be stuck in neutral.

    Here is the general problem:

    Code:
    template< class T, class S>
    
    struct Node
    {
        Node* MyNode;
        T Value;
    }
    
    
    template< class T, class S>
    
    class Myclass
    {
        T GetValue();
        bool operator== (T rhs);
        Node node;
    }
    
    
    // In the case that T is a class, T will look somethink like this.
    
    template< class T, class S>
    
    class MyVector
    {
        int size;
        float length;
        S value;
    }
    Here are the requirements.

    If T is a a primative (int, long, float, double, char...), S will be a primative of the same type

    GetValue will return the value of classInst1.node.value
    The operator== will compare classInst1.node.value == classInst2.node.value


    If T is a class, S will be a primative.

    GetValue will return the value of classInst1.node.value
    The operator== will compare classInst1.node.<T>value.value == classInst2.node.<T>value.value


    so I could have a program like this:

    Code:
    main()
    {
        Myclass<int, int>         Foo1;
        Myclass<int, int>         Foo2;
        Myclass<MyVector, float>  Bar1;
        Myclass<MyVector, float>  Bar2;
    
        int      myInt  = Foo1.GetValue(); //returns Foo1.node.value
        MyVector myVect = Bar1.GetValue(); //returns Bar1.node.value
    
        if ( Foo1 == Foo2 ){}  //compares Foo1.node.value       == Foo2.node.value
        if ( Bar1 == Bar2 ){}  //compares Bar1.node.value.value == Bar2.node.value.value
    }
    Thank in advance for any help.

    byteherder
    Last edited by byteherder; 07-31-2011 at 04:21 PM.

  2. #2
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682
    You messed up something. Only the 'Node' class is templated, all the others are not. The following is also invalid:
    Code:
    <int, int>              Foo1;
    <int, int>              Foo2;
    <MyVector, float>  Bar1;
    <MyVector, float>  Bar2;
    You did not specify which class you want to instantiate (Node?):
    Code:
    Node<int, int>              Foo1;
    Node<int, int>              Foo2;
    Node<MyVector, float>  Bar1;
    Node<MyVector, float>  Bar2;
    Do you really know what you want to do?
    I never put signature, but I decided to make an exception.

  3. #3
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    I'll edit the top post. I want the template to be the same for all of the top code block. Thanks for pointing out my mistake.
    Last edited by byteherder; 07-31-2011 at 04:23 PM.

  4. #4
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682
    If T is a class, S will be a primative.
    What primitive will S be then? Your main() is still broken.

    For compile-time type recognition you can use template specialisation. You may not grasp it at once, but here is a hint:

    Code:
    template <typename T>
    class is_fundamental {
    public:
        static const bool result = false;
    };
    template <>
    class is_fundamental<char> {
    public:
        static const bool result = true;
    };
    template <>
    class is_fundamental<int> {
    public:
        static const bool result = true;
    };
    You need to provide specialisation for every primitive. Then you can easily check whether given type is fundamental (unfortunately, this is done at run-time):
    Code:
    if (is_fundamental<int>::result)
    {
        // int is a fundamental type
    }
    I do not even want to mention that all your classes will also need (partial) specialisation.
    Shortly: you need a better (easier that is) way of doing whatever you want to do now.
    Last edited by kmdv; 07-31-2011 at 04:42 PM.
    I never put signature, but I decided to make an exception.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    Quote Originally Posted by kmdv View Post
    What primitive will S be then? Your main() is still broken.

    For compile-time type recognition you can use template specialisation. You may not grasp it at once, but here is a hint:

    Code:
    template <typename T>
    class is_fundamental {
    public:
        static const bool result = false;
    };
    template <>
    class is_fundamental<char> {
    public:
        static const bool result = true;
    };
    template <>
    class is_fundamental<int> {
    public:
        static const bool result = true;
    };
    You need to provide specialisation for every primitive. Then you can easily check whether given type is fundamental (unfortunately, this is done at run-time):
    Code:
    if (is_fundamental<int>::result)
    {
        // int is a fundamental type
    }
    I do not even want to mention that all your classes will also need (partial) specialisation.
    Shortly: you need a better (easier that is) way of doing whatever you want to do now.

    The primative could be any of primative types. I wanted to get away from specifying template specialisation for every single primative type.

    Looking a little deeper into partial template specialisation, I am reading about Boost's enable_if or something like that. This is looking more like a metatemplate problem, where the compiler first has to choose the right template and then fill in that template with the right type.

    Has anyone used the the enable_if before?

    byteherder.

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,302
    What you really want is "type traits". Something like what the yasli_vector has I imagine.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,549
    Check out boost's type traits. It has a is_fundamental for your purpose.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,264
    Quote Originally Posted by kmdv View Post
    Then you can easily check whether given type is fundamental (unfortunately, this is done at run-time):
    Code:
    if (is_fundamental<int>::result)
    {
        // int is a fundamental type
    }
    In your example, the value of is_fundamental<int>::result is used at run time, but the compiler will evaluate it at compile time. Some compilers will, for example, give a warning about testing a condition that (in your example) is always true.

    However, you have provided the core of a solution ....

    Assuming an is_fundamental<> type is specialised as you have shown then the original problem can be addressed through;
    Code:
    template<class T, bool is_fundamental_type = is_fundamental<T>::result > struct MyClass {};
    
    template<class T> struct MyClass<T, false>
    {
        // provide all the operations you want for MyClass instantiated for non-fundamental types
    };
    
    template<class T> struct MyClass<T, true>
    {
        // provide all the operations you want for MyClass instantiated for fundamental types
    };
    Last edited by grumpy; 08-01-2011 at 04:23 AM.
    Right 98% of the time, and don't care about the other 3%.

  9. #9
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    Type traits that was the answer I was looking for, Also, the is_fundamental. Thank you, everyone, for you help.

    byteherder.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Template question
    By darren78 in forum C++ Programming
    Replies: 1
    Last Post: 08-11-2010, 08:47 AM
  2. Template question
    By borat in forum C++ Programming
    Replies: 5
    Last Post: 07-29-2010, 02:52 AM
  3. another template question
    By l2u in forum C++ Programming
    Replies: 4
    Last Post: 02-13-2008, 02:52 PM
  4. Template Question
    By Eber Kain in forum C++ Programming
    Replies: 5
    Last Post: 06-12-2004, 10:07 PM
  5. Another template question
    By grscot in forum C++ Programming
    Replies: 2
    Last Post: 04-28-2003, 06:16 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21