我正在尝试为容器类完成类似Eigen
高级初始化的操作。
即。在main
中,我想填写DynamicArray
类型的对象,如下所示:
的main.cpp
// Create 3 x 3 Dynamic array and fill with 0's
DynamicArray da(3, 3, 0);
da << 1, 2, 3,
4, 5, 6,
7, 8, 9;
我用来尝试实现此目的的方法是:
DynamicArray.hpp
template <typename T>
class DynamicArray {
// ...
public:
// ...
template <typename... Args,
typename = typename std::enable_if<ArgPackSameTruth<
std::is_convertible<Args, T>...>::value,
T>::type
> void operator<<(Args... x) {
typename std::vector<T> arg_vect{std::forward<Args>(x)...};
std::cout << arg_vect.size() << "\n";
// Load contents of arg_vect into *this...
return;
}
}
当我编译main.cpp
时,arg_vect
的大小为1,因此只接受第一个参数。如何确保传递所有参数?
谢谢!
答案 0 :(得分:5)
操作顺序与您的想法不同。如果你有:
da << 1, 2, 3;
它相当于(给定自由运算符):
auto tmp1 = operator<<(da,1);
auto tmp2 = operator,(tmp1,2);
auto tmp3 = operator,(tmp2,3);
因此,您需要大致相同的运营商:
#include <iostream>
struct DynamicArray
{
};
DynamicArray& operator<<( DynamicArray& da, int i )
{
std::cout << "<<" << i << std::endl;
return da;
}
DynamicArray& operator,( DynamicArray& da, int i )
{
std::cout << "," << i << std::endl;
return da;
}
int main()
{
DynamicArray da;
da << 1, 2, 3,
4, 5, 6,
7, 8, 9;
}
当然,您需要将值存储在某处,等等。考虑一个允许这样做的设计,并考虑添加一个中间类来保存operator<<
返回的值,它们同时作为第一个输入参数和operator,
的返回类型。如果需要,该类的析构函数可用于应用收集的中间数据。
答案 1 :(得分:2)
operator <<
只需要1个参数。这就是为什么尺寸为1. 1之后的数字全部未被使用。如果您打开-Wall
,则会收到有关此问题的警告。
我能想到2个解决方案。
一个只是将数字括在大括号{...}
中,让operator <<
接受std::initializer_list<double>
void operator<< (std::initializer_list<double>);
第二个解决方案是动态数组重载operator,
和operator<<
,
和<<
都会返回一个DynamicArray,以便它们可以被链接。
DynamicArray& operator<<(double x){
//Add x to the Dynarray
return *this;
}
operator,
与operator<<
DynamicArray& operator, (double x){
//Add x to the Dynarray
return *this;
}
以下是std::vector
#include <vector>
#include <iostream>
template <typename T>
std::vector<T>&
operator<<(std::vector<T>& x, T y)
{
x.push_back(y);
return x;
}
template <typename T>
std::vector<T>&
operator,(std::vector<T>& x, T y)
{
x.push_back(y);
return x;
}
int main(){
std::vector<int> A;
A << 1,2,3,4,5,6,7,8,9,10;
for(int x : A){
std::cout << x << ",";
}
std::cout << std::endl;
}