Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to pass valarray or vector as argument in C++20

I want a function that can take either a valarray or vector as an argument. The (trivial sample) code below works fine in C++17 (compiles, runs, and gives the right answer), but fails to compile in C++20 with the error message

‘GetSum’: no matching overloaded function found

It works if I call the pointer version directly, but it’s obviously neater if I can just pass the container.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

template<class T>
T GetSum(std::valarray<T>& vIn)
{
    return GetSum(&vIn[0], vIn.size());
}

template<class T>
T GetSum(std::vector<T>& vIn)
{
    return GetSum(&vIn[0], vIn.size());  // could use .data() here
}

// pointer version
template<class T>
T GetSum(T* vIn, size_t n)
{
    T sum{};
    for (size_t i = 0; i < n; ++i)
        sum += vIn[i];
    return sum;
}


void OnTest()
{
    std::vector<double> vec(10, 1);
    std::valarray<int> val(3, 10);

    double x = GetSum(vec);
    int i = GetSum(val);
...

Sorry for my ignorance, but can someone tell me what I am doing wrong?
(FYI I asked a question on this topic a while back, which was how I got the C++17 code working OK, but now I’m trying to move to C++20 and find that my code no longer works).

>Solution :

can someone tell me what I am doing wrong?

The problem is that you’re trying to call the pointer version of GetSum before declaring it. In other words, when you wrote GetSum(&vIn[0], vIn.size()) the compiler can’t find the suitable version because name lookup only considers declaration at or before that point.

To solve this, you can move its declaration before using/calling it as shown below:

//first declare/define this
template<class T>
T GetSum(T* vIn, size_t n)
{
    T sum{};
    for (size_t i = 0; i < n; ++i)
        sum += vIn[i];
    return sum;
}

//now you can use the above
template<class T>
T GetSum(std::vector<T>& vIn)
{
    //now this'll work because we've already declared the pointer version above
    return GetSum(&vIn[0], vIn.size());  
}

template<class T>
T GetSum(std::valarray<T>& vIn)
{
    return GetSum(&vIn[0], vIn.size());
}

Working demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading