C ++如何传递多个参数?

时间:2016-02-21 18:58:24

标签: c++ arrays templates c++11

假设我有一个概率类,其方法可以计算数组的平均值。因为这个方法可能会传递一个float,double,int等数组,所以我认为将这个方法作为模板方法是合适的。

但是在传递数组时,我必须定义数组的类型和数组的长度。所以我的问题是:如何配置模板以接受两个输入?我引用了网络,但看到一个很好的例子,运气有限。

  • 定义模板以接受int,float等参数是否有效?

我发布了我的代码

概率标题

#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

主要

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

int main()
{

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

}

6 个答案:

答案 0 :(得分:3)

问题是您已将源数组定义为糟糕的C数组而不是std::array。如果您将源数组定义为std::array,则不会遇到此问题。

另外,除了你的例子之外,没有必要再传递长度。

答案 1 :(得分:3)

  

定义模板以接受int,floats等参数是否有效?

完全没问题。但要传递一个数组,你必须有一个数组。

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

在相应的模板中,您必须使用size_t,而不是int

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

如何配置模板以接受两个输入?

只需添加其他参数即可。要传递指针和长度,可以创建一个接收指针和长度的模板

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

c样式数组还有一种特殊的语法,允许您在不必指定长度的情况下传递它们,因为该参数将从类型中推断出来。

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

我们一起

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]){};
};

查看实时工作示例here

答案 2 :(得分:2)

请注意,您正在尝试将旧的普通C数组float hoor[]传递给类型为std::array<T,N>的参数,该参数与普通C数组不直接兼容。

通过普通C数组作为参考的正确语法是:

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

用法示例:

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

int hoor_i[] = {3, 3, 1, 1};
ExpectedValueDataSet(hoor_i);

答案 3 :(得分:1)

最终,我觉得以下是你应该做的事情:

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. 尽可能避免使用C风格的数组。
  2. 尽可能支持std::vector
  3. 来自std的所有容器的通用性都很好。
  4. 以上代码满足所有这三个要求,并使用以下示例:

    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 };
    

答案 4 :(得分:0)

实际上你可以拥有多个模板参数,但C ++模板提供了更大的灵活性,你可以直接避免指定你正在处理一个数组,并假设你可以访问size() const方法,{{1 }} typedef和andloaded value_type

这就足够了,所以代码会变成:

operator[]

这是您的实现更通用的,它可以与所有支持上述特征的类一起使用,甚至不用担心它是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; } ,还是std::array或者是什么其他

答案 5 :(得分:0)

将容器传递给这样的模板函数。

#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

使用lambda。 lambdas中的auto关键字需要C ++ 14及更高版本。

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