我学习了多态性的概念,并尝试使用这个概念来创建一个名为“管道”的Map,它接受输入向量(其思想是这些可以是不同的数据结构)并应用于输入函数(在不同的用例中也可以不同地选择该函数)并且产生结果向量(也会因情况而异)。我的想法是尝试以下操作
#include <iostream>
#include <vector>
using namespace std;
struct input
{
};
struct intInput : public input
{
intInput(int x) :x(x) {}
int x;
};
struct result
{
};
struct intResult : public result
{
intResult(int y) :y(y) {}
int y;
};
vector<result> pipeline(vector<input> x, result(*g)(input))
{
std::vector<result> res;
for (size_t i = 0; i < x.size(); i++)
{
res.push_back((*g)(x[i]));
}
return res;
}
intResult doubling(intInput i)
{
intResult res(2 * i.x);
return res;
}
void printing(input i)
{
cout << "hi" << endl;
}
int main()
{
vector<intInput> v{ 1,2,3,4 };
pipeline(v, doubling);
}
但我得到了编译错误
'std::vector<result,std::allocator<result>> pipeline(std::vector<input,std::allocator<input>>,result (__cdecl *)(input))': cannot convert argument 1 from 'std::vector<intInput,std::allocator<intInput>>' to 'std::vector<input,std::allocator<input>>'
有什么办法可以解决这个问题吗?
1条答案
按热度按时间k3bvogb11#
vector<input>
和vector<intInput>
不是多态的,并且永远不会是-vector<input>
知道每个条目是1字节长(最小大小),并且vector<intInput>
知道每个条目是4字节长。但是,您可以通过将
pipeline
设置为模板来实现所需的功能,例如:不需要继承。你可以删除类
input
和result
。编译器将能够根据需要生成这个函数的变体,如下所示:您可以将该函数作为
pipeline<intInput, intResult>(v, doubling);
调用,但也可以在编译器能够自行解决<>
部分时省略它,这样您就可以调用pipeline(v, doubling);
注意,如果你在头文件中声明了这个函数,那么它的定义也应该在同一个头文件中,而不是在.cpp文件中,因为每次编译器看到你调用这个函数时,它必须为那个调用创建正确的函数版本,因此它必须知道函数中有什么代码。
C++中的继承多态性只适用于指针或引用。这是因为所有指针的大小都相同。处理
input*
的代码不必关心在input
末尾后面实际上有一些它不知道的额外变量。(除非它使用指针算法!指针算法不是多态的)你可以有一个指针向量(
vector<input*>
),但这通常有点笨拙,或者你可以做一些返回指针的东西:(此处使用指针完成,但也可以使用引用)正如你所看到的,为了防止
pipeline
函数处理任何实际的结果对象--只有指针--它实际上是丑陋的。对于这个pipeline
函数,模板解决方案确实更好。