c++ - variadic template for sorting variable number of arrays
问题描述
I am trying to write a program to sort unsorted 'n' vectors using variadic templates into one sorted vector. It can be done in other ways but I want to do it this way to better my understanding of variadic templates. I don't know if I can achieve that but below is my attempt at it which is not working.
My understanding is that ultimately sorted_n_vector will be reduced to MergeVector<int> + MergeVector<int> + MergeVectorMergeVector<int>
same as line 50(MergeVector a8(a5 + a6 + a7)) but I think it is wrong. Please help and also give me some code review comments as well.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
#include <string>
template<typename t>
class MergeVector {
public:
std::vector<t> arr_;
MergeVector(std::vector<t> arr) : arr_(arr) {}
auto operator + (MergeVector<t> &obj) {
std::vector<t> dst;
std::sort(arr_.begin(), arr_.end());
std::sort(obj.arr_.begin(), obj.arr_.end());
std::merge(arr_.begin(), arr_.end(), obj.arr_.begin(), obj.arr_.end(), std::back_inserter(dst));
MergeVector res(dst);
return res;
}
friend auto& operator<<(std::ostream &os, MergeVector<t>& mv)
{
std::copy(mv.arr_.begin(), mv.arr_.end(), std::ostream_iterator<t>(os, " "));
return os;
}
};
template<typename t>
auto sorted_n_vector(t vec)
{
return vec;
}
template<typename t, typename... vectors>
auto sorted_n_vector(t vec, vectors... args)
{
return vec + sorted_n_vector(args...);
}
int main() {
std::vector<int> a1 = {1, 2, 3};
std::vector<int> a2 = {4, 5, 6};
std::vector<int> a3 = {7, 8, 9};
MergeVector<int> a5(a1);
MergeVector<int> a6(a2);
MergeVector<int> a7(a3);
MergeVector<int> a8(a5 + a6 + a7); //---- Line 50
std::cout << a8 << std::endl;
#if 1
MergeVector<int> a9(sorted_n_vector(a5, a6, a7));
std::cout << a9 << std::endl;
#endif
return 0;
}
I am getting below error:
test.cpp:40:20: error: invalid operands to binary expression ('MergeVector<int>' and 'MergeVector<int>')
return vec + sorted_n_vector(args...);
~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:40:22: note: in instantiation of function template specialization 'sorted_n_vector<MergeVector<int>, MergeVector<int> >' requested here
return vec + sorted_n_vector(args...);
^
test.cpp:54:22: note: in instantiation of function template specialization 'sorted_n_vector<MergeVector<int>, MergeVector<int>, MergeVector<int> >' requested here
MergeVector<int> a9(sorted_n_vector(a5, a6, a7));
^
test.cpp:15:7: note: candidate function not viable: expects an l-value for 1st argument
auto operator + (MergeVector<t> &obj) {
解决方案
sorted_n_vector
具有指定为的返回类型auto
,因此它将返回一个临时对象,而不是对其他对象的引用。
您尝试operator+
将此临时作为参数调用,但operator+
需要一个非常量(左值)引用参数。
禁止将临时变量(或者更确切地说是右值表达式)绑定到非 const(左值)引用,因此编译器不会考虑调用您operator+
,而是会在其他地方搜索。
没有找到任何替代调用+
,它会为您提供您所看到的错误消息。
解决方法是将参数operator+
作为 const 引用:
auto operator + (const MergeVector<t> &obj) {
将临时变量(右值表达式)绑定到 const(左值)引用是允许的,并且可以按预期工作。
编辑:
但是,这会引发另一个错误,因为您operator+
实际上是在修改obj
and this
。虽然您可以通过按值而不是按引用来解决这个问题,但这是一个不寻常的设计。通常+
预计不会修改其参数。如果c = a+b
因为a
或b
不允许修改而失败,那将是令人惊讶的。您可以通过在MergeVector
构造函数中进行排序来实现这一点:
MergeVector(std::vector<t> arr) : arr_(arr) {
std::sort(arr_.begin(), arr_.end());
}
然后你可以把这些std::sort
线放进去,你可以在两个参数中operator+
完全做到:const
auto operator + (const MergeVector<t> &obj) const {
推荐阅读
- google-cloud-platform - Stackdriver IoT 设备监控
- angular - 我想让这个角度代码返回多个结果而不是一个
- azure-active-directory - 将 Azure 服务管理 REST API 用作已注册的 Active Directory 应用程序
- visual-studio-2019 - Visual Studio 2019 预览版 - 自动完成未选择第一个或任何选项
- python - Pandas 数据框捕获具有多个列的行,其中填充了常量
- wordpress - 在 Wordpress 单个博客文章中的“the_title”之后和“the_content”之前放置一个片段
- python-3.x - 如何在不循环的情况下将数据扩充后的图像保存在新文件夹中
- javascript - 单击按钮时重定向到 laravel 路由链接
- apache-kafka - 如何在 StreamSets Data Collector 中加入多个 Kafka 主题?
- git - 使用 VSCode 远程 SSH 时,如何在服务器端的 PATH 中添加一些内容?