Skip to main content
fixed typo
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Some more tips:

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]>is_floating_point_array<T[size]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Some more tips:

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Some more tips:

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[size]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

deleted 38 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Template metaprogrammingSome more tips (the most lovely part):

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Template metaprogramming tips (the most lovely part):

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Some more tips:

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

added 1382 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Template metaprogramming tips (the most lovely part):

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Different approach:

I'd use iterators and standard library. Using them it becomes really simple:

template <typename ForwardIt, typename T = typename std::iterator_traits<ForwardIt>::value_type>
T average(ForwardIt first, ForwardIt last, T initvalue = {}) //will be 0 for builtins
{
    auto distance = std::distance(first, last);
    auto result = std::accumulate(first, last, initvalue);

    return result / distance;
}

It is also possible to have a distance argument that will be defaulted to what std::distance() produces, but since my use cases are mostly bound to RandomAccessIterators, I don't care, since distance is constant time on random access iterators.

It can be noticed that iterators abstract container type, so they become really easy to use.

The code actually is part of my library. It is so ancient that I forgot it even exists.

As for sum, it is simply using std::accumulate().

Template metaprogramming tips (the most lovely part):

Standard library has type traits. They help to debug templates. The toolbox should try to provide them as well.

template <typename T>
struct is_floating_point_array :
                public std::false_type 
{};

template <typename T, std::size_t size>
struct is_floating_point_array<T[N]> :
                public std::bool_constant<std::is_floating_point_v<T>>                    
{};

//one for std::array

Ironically, std::is_array<> won't work on instantiations of std::array, so I recommend writing your own. The above will not only provide easier debugging experience, but will also allow tagged dispatch or if constexpr opportunities. Even more, it will provide concept support, which will make metaprogramming even easier. I didn't directly inherit from std::bool_constant on the first phase since I favored readability to less code height, maybe I was wrong.

Iterators are essential part of standard library. I recommend using them at least in obvious cases. Currently using the code one needs to use std::size() or write one themselves. Pretty much everyone I know doesn't know about std::size(). std::begin() and std::end() (or their member counterparts) destroy opportunity for making the mistakes.

Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
Loading