假设我有一个概率类,其方法可以计算数组的平均值。因为这个方法可能会传递一个float,double,int等数组,所以我认为将这个方法作为模板方法是合适的。
但是在传递数组时,我必须定义数组的类型和数组的长度。所以我的问题是:如何配置模板以接受两个输入?我引用了网络,但看到一个很好的例子,运气有限。
我发布了我的代码
概率标题
#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);
}
答案 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();
}
std::vector
。std
的所有容器的通用性都很好。以上代码满足所有这三个要求,并使用以下示例:
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