Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ How Do You Pass Multiple Parameters?

Let's assume I have a probability class with a method that computes the average of an array. Because it's possible that this method be passed an array of floats, doubles, ints, etc, I assumed it would be appropriate to make this method a template method.

But when passing an array, I have to define a the type of array and length of an array. So my question is: how do I configure the template to accept two inputs? I have referenced the web but have had limited luck in seeing a good example.

  • Is it valid to define templates to accept parameters that are ints, floats, etc.?

I've posted my code below

Probability Header

#ifndef COFFEEDEVMATH_PROBABILITY_H
#define COFFEEDEVMATH_PROBABILITY_H

class Probability
{
    public:
         Probability(void);
        template <typename T, int N>
        void ExpectedValueDataSet(const std::array<T, N>& data)
        {
            T test = data[0]; // This is irrelevant, but simply a place holder example.
        }

    protected:
    private:
};

#endif // COFFEEDEVMATH_PROBABILITY_H

Main

#include <iostream>
#include <Probability.h>

int main()
{

    float hoor[] = {3, 3, 1, 1};
    Probability prob;
    prob.ExpectedValueDataSet(hoor, 4);

}
like image 669
Izzo Avatar asked Feb 21 '16 18:02

Izzo


4 Answers

The problem is that you've defined your source array as a shitty C array instead of a std::array. If you define your source array as a std::array, you won't have this problem.

Also, there's no need to pass the length in addition, as you have with your example.

like image 20
Puppy Avatar answered Oct 18 '22 04:10

Puppy


Is it valid to define templates to accept parameters that are ints, floats, etc.?

It's perfectly fine. But to pass an array, you must have an array.

std::array<float,4> hoor2 = {3.0f, 3.0f, 1.0f, 1.0f};

In the corresponding template you must use size_t, not int

template <typename T, size_t N>
void ExpectedValueDataSet(const std::array<T, N>& data) {}

how do I configure the template to accept two inputs?

Just add an additional parameter. To pass a pointer and a length, you create a template that receives a pointer and a length

template <typename T>
void ExpectedValueDataSet( T const * data, int N){}

There is also a special syntax for c style arrays that will allow you to pass them without having to specify the length, as that argument will be deduced from the type.

template <typename T, size_t N >
void ExpectedValueDataSet( const T (&data)[N]) { }

Together we have

class Probability
{ 
public:
    template <typename T, size_t N>
    void ExpectedValueDataSet(const std::array<T, N>& data) {}

    template <typename T>
    void ExpectedValueDataSet( T const * data, int N){}

    template <typename T, size_t N>
    void ExpectedValueDataSet(const T (&data)[N]){};
};

See live working exampe here

like image 184
Thomas Avatar answered Oct 18 '22 05:10

Thomas


Please note that you are trying to pass old plain C array float hoor[] to function with parameter of type std::array<T,N> which is NOT directly compatible with plain C array.

Correct syntax to pass plain C array as reference is:

template <size_t N, typename T>
void ExpectedValueDataSet(const T (&data)[N])
{
    T test = data[0];
}

Usage example:

float hoor_f[] = {3, 3, 1, 1};
ExpectedValueDataSet(hoor_f);

int hoor_i[] = {3, 3, 1, 1};
ExpectedValueDataSet(hoor_i);
like image 2
Rost Avatar answered Oct 18 '22 04:10

Rost


Ultimately, I have a feeling that the following is what you should be doing:

template<typename C>
typename C::value_type average(C const& c)
{
    return std::accumulate(std::begin(c), std::end(c), C::value_type{}) / c.size();
}
  1. Avoid C-style arrays whenever possible.
  2. Favor std::vector whenever possible.
  3. Genericity over all containers from std is good.

The above code satisfies all three and works with the following examples:

std::vector<double> vd = { 0., 1., 3., 4.4 };
std::array<float, 4> af = { 3.f, 5.f, 6.f };
std::list<int> li = { 1, 2, 3 };
like image 1
screwnut Avatar answered Oct 18 '22 03:10

screwnut