如何存储数据类型<T>
的值?我尝试做的是拥有一个适用于long
或double
类型的功能。例如,返回5个数字的中位数(因为现在我有两个类,一个用于long,一个用于double)。我不知道如何做的两件事:
<T>
值<T>
的函数中调用返回类型为<T>
的函数这是非工作代码,剥离可读。代码适用于Arduino(或其他类似的微控制器)。谢谢。
//how to store custom type?
//in practice, this may be a single value, array,
//or struct with one of the members being T
T values[5]={2,6,8,9,11};
//public
template <typename T> T getFirst (){
T result = getPos[0];
return result;
}
//private
template <typename T> T getPos (byte index){
T result = values[index];
return result;
}
void setup() {
// put your setup code here, to run once:
double k;
k=getFirst()
}
void loop() {
// put your main code here, to run repeatedly:
}
编辑4,最终的想法: 由于一些用户报告的编辑太多,我决定删除所有内容。我只留下原来的问题。我将在一个新的,独立的anwser中给出我的最终发现。
答案 0 :(得分:1)
修改此答案已不再适用,因为问题已大幅改变。 (结束编辑)
计算5个值的中位数的函数需要获得5个值作为参数。这可以是标准容器或指向遗留数组或一对迭代器的普通指针。该功能不需要关心这些值的存储。来电者存储它们。
template <typename T>
T median_of_5 (const std::array<T, 5>&); // a standard no-overhead container
template <typename T>
T median_of_5 (const T*); // a legacy array
template <typename Iter>
decltype(*std::declval<Iter>())
median_of_5 (Iter first, Iter last); // two iterators
// or another way
template <typename Iter>
typename std::iterator_traits<Iter>::value_type
median_of_5 (Iter first, Iter last); // two iterators
如果函数模板需要临时存储类型T的某些数据,只需在函数中声明它:
template <typename T>
T median_of_5 (const std::array<T, 5>&)
{
T values[5]; // no problem here
...
}
如果您不需要使用泛型类型T在任何函数模板之外存储五个值,并且可以使用C ++ 14,则可以使用变量模板:
template <typename T>
T values[5] { 2,6,8,9,11 };
但这很可能不是你所需要的。
答案 1 :(得分:1)
你的意思是这样吗?
template<typename T>
class medianbuffer{
public:
// Should work like this
medianbuffer() { /**/ }
~medianbuffer() { /**/ } // "~" = destructor , no expecting to happen
T getFirst (){
T result = getPos(0);
return result;
}
private:
T getPos (byte index){
T result = values[index];
return result;
}
T values[5]={2,6,8,9,11};
};
使用模板typename的所有函数都必须在头文件AFAIK中定义。
然后,您将使用每种类型的一个medianbuffer类。所有功能仍然需要定义。
答案 2 :(得分:0)
所以,我现在有一些调查结果。
<T>
类型更好或仅使用这种方式(不知道何时)。在写这篇文章的那一刻,这就是我所知道的。我的猜测是,在接下来的几年中,很多人可能会在这里绊倒,并且知道更好的人试图给出一些更好的解释,或者至少填补空白。
/*Before class with prototypes, indicate that Template T will be used
not sure when to use first or second line, seems that both work in this scenario*/
//template<class T>
template<typename T>
class medianbuffer{
public:
medianbuffer() { /**/ } //since no cpp will be used, do not forget to create proper functions {} in this file
~medianbuffer() { /**/ }
T getFirst();
//you may also try to define it here
//T getFirst();{
// T result = getPos(1);
// return result;
//}
private:
T getPos (byte index){
T result = values[index];
return result;
}
T values[5]={2,6,8,9,11};
};
//Here is one of your bigest time waste, and it's not an obvious one - put all in one file!
/*The following part is usually in cpp files, but you will see a lot of "undefined" or similar warnings
Because templates are compiled when required, this forces a restriction for multi-file projects:
the implementation (definition) of a template class or function must be in the same file as its declaration.
That means that we cannot separate the interface in a separate header file,
and that we must include both interface and implementation in any file that uses the templates.
http://www.cplusplus.com/doc/oldtutorial/templates/
*/
//if writing methods here, remember that every method must have "template" in front,
//do not forget to put <T>, since you will get a lot of cryptic errors
template<typename T>
T medianbuffer<T>::getFirst(){
T result = getPos(1);
return result;
}
//type of T is actually passed to its class this way
medianbuffer <double>mb_d;
medianbuffer <int> mb_i;
void setup() {
Serial.begin(57600);
debug();
}
void debug(){
//class instantiated as double, you can use it normaly
double first_d=mb_d.getFirst();
Serial.print("\n double type --> ");
Serial.print(first_d);
//class instantiated as int
int first_i=mb_i.getFirst();
Serial.print("\n int type --> ");
Serial.print(first_i);
}
void loop() {
// put your main code here, to run repeatedly:
}
先生,谢谢。和FredyKay,非常感谢你的帮助。