C ++ How do you pass multiple parameters?

Suppose I have a probability class with a method that calculates the average value of an array. Since it is possible that an array of float, double, ints, etc. will be passed to this method, I suggested that it would be advisable to make this method a template.

But when passing the array, I have to determine the type of the array and the length of the array. Therefore, my question is: how to configure the template to accept two inputs? I referenced the Internet, but had limited luck seeing a good example.

  • Is it possible to define patterns for accepting parameters that are ints, floats, etc.?

I posted my code below

Probability heading

#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 

home

 #include <iostream> #include <Probability.h> int main() { float hoor[] = {3, 3, 1, 1}; Probability prob; prob.ExpectedValueDataSet(hoor, 4); } 
+6
source share
6 answers

Is it possible to define patterns for accepting parameters that are int, float, etc.?

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

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

In the appropriate template, you should use size_t , not int

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

How to set up a template for receiving two inputs?

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

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

There is also a special syntax for arrays of c styles that allow you to pass them without specifying the length, since this argument will be inferred from this 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 a live working exam here

+3
source

The problem is that you defined your source array as shitty C array instead of std::array . If you define your source array as std::array , you will not have this problem.

In addition, there is no need to pass the length additionally, as in your example.

+3
source

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

The correct syntax for passing a simple C array as a reference:

 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); 
+2
source

Ultimately, I get the feeling that you should do the following:

 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(); } 
  • Avoid C-style arrays whenever possible.
  • Thank std::vector whenever possible.
  • The usefulness of 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 }; 
+1
source

You can actually have several template arguments, but C ++ templates offer even more flexibility, you can directly avoid specifying that you are dealing with an array, and assume that you will have access to the size() const method size() const , value_type typedef and and operator[] overloaded.

That would be enough, so the code would become something like:

 template <typename T> void calculate(const T& data) { size_t length = data.size(); using type = typename T::value_type; type value = data[0]; cout << length << " " << value << endl; } 

This is a more general implementation, it will be able to work with all classes that support the above characteristics, without even worrying about whether it is std::array or perhaps std::vector or what else.

0
source

Pass the container to a template function like this.

 #include <iostream> template<typename T> double average(T t) { auto tmp = 0.0; for (auto &i : t) { tmp += i; } return tmp/t.size(); } using namespace std; int main(int argc, char const *argv[]) { auto a = {1.0, 1.1, 1.2, 1.3}; auto b = {2, 3, 4, 5}; auto x = average(a); auto y = average(b); cout << "x: " << x << endl; cout << "y: " << y << endl; return 0; } 

x: 1.15
y: 3,5

And using lambda. The auto keyword in lambdas requires C ++ 14 and later.

 auto average = [](auto v){ auto tmp = 0.0; for (auto& i : v) { tmp += i; } return tmp/v.size(); }; auto a = {1.1, 1.2, 1.3, 1.4}; auto b = {2, 3, 4, 5, 6, 7, 8, 9}; auto x = average(a); auto y = average(b); cout << "x: " << x << endl; cout << "y: " << y << endl; 

x: 1.25
y: 5.5

0
source

All Articles