traits class (whats it all about?)

Discussion in 'C++' started by Bit Byte, Nov 23, 2006.

  1. Bit Byte

    Bit Byte Guest

    Can't seem to get my head around the point of a trait class - no matter
    how many times I read up on it - why not simply use functors or function
    pointers ?

    Anyone care to explain this in a simple straightforward way that a
    simple guy from "Missourah" can understand ?
     
    Bit Byte, Nov 23, 2006
    #1
    1. Advertising

  2. Bit Byte

    Deniel Rose' Guest

    perhaps due to trait timetable personally set up to feed itself,
    nothing that really matters much to the heir !
    well, pretty off-topical explanation though but I'd rather think of a
    modern model for the shelter at millions of dollars after all rather
    than turning myself to be knittie-pickie over what a trait is dealing
    with fAnct0rs, :p

    Bit Byte wrote:
    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?
     
    Deniel Rose', Nov 23, 2006
    #2
    1. Advertising

  3. Bit Byte

    Bit Byte Guest

    Deniel Rose' wrote:

    > perhaps due to trait timetable personally set up to feed itself,
    > nothing that really matters much to the heir !
    > well, pretty off-topical explanation though but I'd rather think of a
    > modern model for the shelter at millions of dollars after all rather
    > than turning myself to be knittie-pickie over what a trait is dealing
    > with fAnct0rs, :p
    >
    > Bit Byte wrote:
    >
    >>Can't seem to get my head around the point of a trait class - no matter
    >>how many times I read up on it - why not simply use functors or function
    >>pointers ?
    >>
    >>Anyone care to explain this in a simple straightforward way that a
    >>simple guy from "Missourah" can understand ?

    >
    >


    Huh ?
     
    Bit Byte, Nov 23, 2006
    #3
  4. Bit Byte

    Salt_Peter Guest

    Bit Byte wrote:
    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?


    Sure you can use functions/functors. But why have to rewrite them if
    you can classify templates by the class traits? Instead of specializing
    one template specificly for one type, classify reusable templates on
    traits.

    Consider following the discussion at:
    http://www.boost.org/doc/html/boost_typetraits.html

    And consult the examples there as well.
     
    Salt_Peter, Nov 23, 2006
    #4
  5. Bit Byte

    dasjotre Guest

    Bit Byte wrote:
    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?


    "Think of a trait as a small object whose main purpose
    is to carry information used by another object or
    algorithm to determine "policy" or "implementation details"."
    [Bjarne Stroustrup]

    a simple example would be copy algorithm
    template<class InIt, class OutIt>
    OutIt copy(InIt from, InIt to, OutIt dest)
    {
    while(from != to)
    {
    *dest = *from;
    ++from, ++dest;
    }
    return dest;
    }

    Now consider a situation like this
    char som_str[100];
    ....
    char dest_str[100];
    you could use the above function
    copy(som_str, som_str+100, dest_str);

    but the best way would be to simply
    copy memory

    so you write another version of copy

    template<class InIt, class OutIt>
    OutIt copy(InIt from, InIt to, OutIt dest)
    {
    memcpy(dest, from, to-from);
    return dest+(to-from);
    }

    Now you need some way to tell the compiler
    which version to use

    so you've come to a situation where if
    InIt and OutIt are pointer types and they
    point to objects of POD type you want to
    use the second version. But if they are
    something else you need the first version.

    So you write a traits class by combining
    the type traits (these are from boost)
    template<class InIt, class OutIt>
    struct memcopyable
    {
    // so value will be compile time constant
    // which will be true if InIt and OutIt satisfy
    // the memcopyable requirement
    enum { value =
    boost::is_pointer<InIt>::value &&
    boost::is_pod<boost::remove_pointer<InIt>::type >::value &&
    boost::is_pointer<OutIt>::value &&
    boost::is_pod<boost::remove_pointer<OutIt>::type >::value };
    };


    Now provide two implementations
    One for memcopyable, and one for others

    template<bool memcopyable>
    struct copy_implementation;

    template<>
    struct copy_implementation<false>
    {
    template<class InIt, class OutIt>
    static OutIt copy(InIt from, InIt to, OutIt dest)
    {
    while(from != to)
    {
    *dest = *from;
    ++from, ++dest;
    }
    return dest;
    }
    };

    template<>
    struct copy_implementation<true>
    {
    template<class InIt, class OutIt>
    static OutIt copy(InIt from, InIt to, OutIt dest)
    {
    memcpy(dest, from, to-from);
    return dest+(to-from);
    }
    };

    template<class InIt, class OutIt>
    OutIt copy (InIt from, InIt to, OutIt dest)
    {
    return copy_implementation<memcopyable<InIt,
    OutIt>::value>::copy(from, to, dest);
    }

    So when you call it as above

    char som_str[100];
    ....
    char dest_str[100];
    copy(som_str, som_str+100, dest_str);

    the compiler will magically select the
    memcopy version
     
    dasjotre, Nov 23, 2006
    #5
  6. Bit Byte

    benben Guest

    Bit Byte wrote:
    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?
    >


    Let's say you need to sum a range of numbers, and you start by:

    template <typename Itr>
    RETVAL_T sum_up(Itr begin, Itr end)
    {
    RETVAL_T sum = 0;

    for (Itr i = begin; i != end; ++i)
    {
    sum += *i;
    }

    return sum;
    }

    All is good except you don't know what RETVAL_T is. You are only given
    the iterator type and that can be anything. You need to know what value
    type corresponds to that iterator type.

    No problem, use traits. A traits class is what you relate some
    compile-time information with a specific type. The
    std::iterator_traits<> template relates value type with a specific
    iterator type, so we do:

    template <typename Itr>
    typename std::iterator_traits<Itr>::value_type // RETVAL_T
    sum_up(Itr begin, Itr end)
    {
    typename std::iterator_traits<Itr>::value_type sum = 0;

    for (Itr i = begin; i != end; ++i)
    {
    sum += *i;
    }

    return sum;
    }

    Hope this is simple enough for you to grasp!

    Regards,
    Ben
     
    benben, Nov 24, 2006
    #6
  7. Bit Byte

    Daniel T. Guest

    Bit Byte <> wrote:

    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?


    Just in case the earlier explanations didn't help...

    A traits class is a way to add compile time information to a class
    without actually putting it in the class. The reason this is useful is
    because with a traits class, one can add compile time information to
    intrinsic types (like int, and double,) and types you didn't write and
    can't change (like string, list and classes from some vendor.)

    It's just that simple.

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 24, 2006
    #7
  8. Bit Byte

    Noah Roberts Guest

    Salt_Peter wrote:
    > Bit Byte wrote:
    > > Can't seem to get my head around the point of a trait class - no matter
    > > how many times I read up on it - why not simply use functors or function
    > > pointers ?
    > >
    > > Anyone care to explain this in a simple straightforward way that a
    > > simple guy from "Missourah" can understand ?

    >
    > Sure you can use functions/functors.


    Actually, you can't. Many uses of traits, in fact the primary use of
    them, simply cannot be provided by functions or functors. Take for
    instance code like this:

    template < typename Iter_t >
    void f(Iter_t)
    {
    std::iterator_traits<Iter_t>::value_type x;
    x = *Iter_t;

    ....
    }

    How are you going to provide the functionality needed to declare x
    using a function or functor?

    Since C++ has no meta objects (during runtime) you simply can't provide
    that type of functionality in a generic manner using functions or
    functors. It's got to be a metafunction or trait blob.

    And that should answer the OP's question.
     
    Noah Roberts, Nov 24, 2006
    #8
  9. Bit Byte

    kwikius Guest

    Bit Byte wrote:
    > Can't seem to get my head around the point of a trait class - no matter
    > how many times I read up on it - why not simply use functors or function
    > pointers ?
    >
    > Anyone care to explain this in a simple straightforward way that a
    > simple guy from "Missourah" can understand ?


    Below is another example of how traits classes can be used and why you
    might want to. Also see:

    http://www.boost.org/doc/html/boost_typetraits.html which has an
    is_pointer type_trait.
    std::char_traits in <string> and std::numeric_limits in <limits>
    for other examples of commonly used traits classes. Note that recent
    designs tend to favour one traits per traits class like the is_pointer
    example rather than putting many in one class like char_traits and
    numeric_limits.

    For more advanced uses and 'metaprogramming" see

    http://www.boost.org/libs/mpl/doc/index.html

    and

    http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.html


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

    #include <iostream>

    // traits class providing info whether T is a pointer
    // preferable to use boost or std::tr1 version in practise
    template <typename T>
    struct is_pointer{
    static const bool value = false;
    };

    template <typename T>
    struct is_pointer<T*> {
    static const bool value = true;
    };

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

    // a functor class specialised (below) on whether T is a pointer
    // the default argument is never meant to be used by the user
    // and would usually be hidden but exposed here to show the workings.

    template <typename T, bool Condition = is_pointer<T>::value>
    struct static_pointer_info_about;

    // the specialisations
    template <typename T>
    struct static_pointer_info_about<T, true>{
    void operator()()const
    {
    std::cout << typeid(T).name() << " is a pointer\n";
    }
    };

    template <typename T>
    struct static_pointer_info_about<T, false>{
    void operator()()const
    {
    std::cout << typeid(T).name() << " is not a pointer\n";
    }
    };

    // a function that wraps the low level stuff a bit
    template <typename T>
    void pointer_info_about( T t)
    {
    static_pointer_info_about<T> f;
    f();
    }

    // and use ..
    int main()
    {
    const char* hello = "hello"; // hello is a pointer
    int n = 1; // int is not

    pointer_info_about(hello);
    pointer_info_about(n);

    }

    regards
    Andy Little
     
    kwikius, Nov 24, 2006
    #9
  10. On Thu, 23 Nov 2006 15:14:45 +0000, Bit Byte wrote:
    >Can't seem to get my head around the point of a trait class - no matter
    >how many times I read up on it


    http://www.cantrip.org/traits.html
     
    Roland Pibinger, Nov 24, 2006
    #10
    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. Replies:
    2
    Views:
    7,922
  2. Diego Martins
    Replies:
    5
    Views:
    488
    Diego Martins
    Sep 5, 2006
  3. Hong Ye
    Replies:
    5
    Views:
    376
    Naresh Rautela
    Jun 2, 2007
  4. greek_bill
    Replies:
    3
    Views:
    540
    greek_bill
    Nov 2, 2008
  5. ray
    Replies:
    1
    Views:
    1,339
    Robert Kern
    Jun 4, 2010
Loading...

Share This Page