Search code examples
c++arraystemplatesoperator-overloading

Operator overload for std::array template?


I want a simple way of having a fixed-size array of floats to be elementwise multiplied with one another. I've written the following code to try to implement this:

#include <array>
#include <cstdint>

template <uint16_t N>
using color = std::array<float,N>;

template <uint16_t N>
constexpr color<N> operator* (color<N> lhs, const color<N>& rhs)
{
    for (int i = 0; i < N; i++){
        lhs[i] *= rhs[i];
    }
    return lhs;
};

int main()
{
    constexpr uint16_t N = 10;

    color<N> myColor{1,2,3,4,5,6,7,8,9,10};
    color<N> myColor2{2,4,6,8,10,12,14,16,18,20};
    
    color<N> mult = myColor * myColor2;

    return 0;
};

When compiled with gcc, I get the following error:

test.cpp: In function ‘int main()’:
test.cpp:23:29: error: no match for ‘operator*’ (operand types are ‘color<10>’ {aka ‘std::array<float, 10>’} and ‘color<10>’ {aka ‘std::array<float, 10>’})
   23 |     color<N> mult = myColor * myColor2;
      |                     ~~~~~~~ ^ ~~~~~~~~
      |                     |         |
      |                     |         array<[...],[...]>
      |                     array<[...],[...]>
test.cpp:8:20: note: candidate: ‘template<short unsigned int N> constexpr color<N> operator*(color<N>, color<N>&)’
    8 | constexpr color<N> operator* (color<N> lhs, const color<N>& rhs)
      |                    ^~~~~~~~
test.cpp:8:20: note:   template argument deduction/substitution failed:
test.cpp:23:31: note:   mismatched types ‘short unsigned int’ and ‘long unsigned int’
   23 |     color<N> mult = myColor * myColor2;
      |                               ^~~~~~~~

Is there a way of having a template of an operator overload? Or is there a more sensible way of going about this?


Solution

  • uint16_t is not the correct type. std::array uses std::size_t for N, so if you want to use std::array then use std::size_t:

    template <std::size_t N>
    //        ^^^^^^^^^^^
    using color = std::array<float, N>;
    
    template <std::size_t N>
    //        ^^^^^^^^^^^
    constexpr color<N> operator* (color<N> lhs, const color<N>& rhs)