所以我有这个测试用例,我试图不必进行一百万个运算符重载或处理重载冲突或复杂性。我希望能够处理带有运算符重载的文字数组常量。这是为预期库创建易用性的一种要求(此测试用例朝着相同的方向发展。)
我正在寻找一种能够添加、减去可变长度的数组文字常量的解决方案。我有一些解决方案,一个可行但前提是 C_COORDS 和 N_COORDS 都不止一个。我使用定义而不是模板来简化测试用例,但这些定义将在最后一小时被模板替换。
欢迎任何建议。请注意,我确信我可以更清楚地说明这一点,但目前看不出如何。30 年前,我曾经做过很多 C 编程。但是从那以后没有太多接触CPP,是的,我主要了解CPP以及它与旧C之间的区别,但还没有太多经验。我只是注意到,因为我确信我错过了一些明显的东西。谢谢。我的测试用例如下......
/** Coord.cpp */
#include <iostream>
#include <cstring>
#include <initializer_list>
#include <cassert>
#define T_COORDS float // the type of coordinates
#define N_COORDS (2) // the coordinates per item
#define C_COORDS (2) // the number of coordinate items
#define L_COORDS (N_COORDS*C_COORDS) // the number of coordinate items
using namespace std;
class Coords {
public:
T_COORDS coords[L_COORDS];
Coords()
{
memset(this->coords, 0, sizeof(Coords));
}
Coords(const T_COORDS inits[L_COORDS])
{
memmove(this->coords, &inits, sizeof(Coords));
}
Coords(initializer_list<T_COORDS> inits) : coords{}
{
copy( inits.begin(), next( inits.begin(), L_COORDS ), coords );
}
friend Coords operator + (const Coords &coords0, const Coords &coords1)
{
Coords result = coords0;
for (int i=0; i < L_COORDS; i++)
result.coords[i] += coords1.coords[i];
return result;
}
/* original that complains about taking size from a temporary array. the next
* 2 UNCOMMENTED overloads accept a fixed length array, but then I have to
* have for every case and they cannot overlap.
friend Coords operator + (const Coords& coords0, const T_COORDS (& coords1)[])
{
int n = sizeof(coords1) / sizeof(T_COORDS);
if ( ! n || n > L_COORDS || n % N_COORDS )
throw "coordinate count must be a multiple and at least N_COORDS and not more then T_COORDS";
cout << "n = " << n << endl;
Coords result = coords0;
for (int i=0; i < L_COORDS; i++)
result.coords[i] += coords1[i%n];
return result;
}
*/
/* bad solution was to make to overloads that match of a fixed length array,
* however it sucks because if N_COORDS is 1, then it also won't compile
* because it ends up with duplicate overloads as L_COORDS is equal to
* C_COORDS when N_COORDS is one, and same is true is C_COORDS is one.
* WHat I hope for is a way to accept any array or at least any array with a
* length >= and on boundaries of C_COORDS and not more the L_COORDS */
friend Coords operator + (const Coords& coords0, const T_COORDS (& coords1)[C_COORDS])
{
int n = sizeof(coords1) / sizeof(T_COORDS);
if ( ! n || n > L_COORDS || n % N_COORDS )
throw "coordinate count must be a multiple and at least N_COORDS and not more then T_COORDS";
cout << "n = " << n << endl;
Coords result = coords0;
for (int i=0; i < L_COORDS; i++)
result.coords[i] += coords1[i%n];
return result;
}
/* as above, so below but for different size array */
friend Coords operator + (const Coords& coords0, const T_COORDS (& coords1)[L_COORDS])
{
int n = sizeof(coords1) / sizeof(T_COORDS);
if ( ! n || n > L_COORDS || n % N_COORDS )
throw "coordinate count must be a multiple and at least N_COORDS and not more then T_COORDS";
cout << "n = " << n << endl;
Coords result = coords0;
for (int i=0; i < L_COORDS; i++)
result.coords[i] += coords1[i%n];
return result;
}
};
void print_coords(const char* label, Coords coords)
{
cout << label << ": ( " << coords.coords[0];
for (int i=1; i < L_COORDS; i++) {
cout << ", " << coords.coords[i];
}
cout << " }" << endl;
};
int main () {
Coords coords0;
print_coords("coords0", coords0);
Coords coords1 {4,5,6,7};
print_coords("coords1", coords1);
Coords coords2 {8,9,10,11};
print_coords("coords2", coords2);
Coords coords3 = coords1 + coords2;
print_coords("coords3", coords3);
T_COORDS tmp[] = {-2,-2,-2,-2};
Coords coords4 = coords3 + tmp;
print_coords("coords4", coords4);
T_COORDS tmp2[] = {-2,-2};
Coords coords5 = coords4 + tmp2;
print_coords("coords5", coords5);
Coords coords6 = coords5 + (T_COORDS[]){10,20,30,40};
print_coords("coords6", coords6);
Coords coords7 = coords6 + (T_COORDS[]){10,20};
print_coords("coords7", coords7);
/* this won't compile with fixes length overloads because it don't match and thats ok.
try {
Coords coords8 = coords7 + (T_COORDS[]){10,20,30};
print_coords("coords8", coords8);
} catch (const char* msg) {
cout << "threw exception on 3 coordinates as expected" << endl;
}
*/
cout << "Done!" << endl;
return 0;
}
/**
* g++ Coord.cpp -o coord
* ./coord
* RESULING OUTPUT:
* coords0: ( 0, 0, 0, 0 }
* coords1: ( 4, 5, 6, 7 }
* coords2: ( 8, 9, 10, 11 }
* coords3: ( 12, 14, 16, 18 }
* n = 4
* coords4: ( 10, 12, 14, 16 }
* n = 2
* coords5: ( 8, 10, 12, 14 }
* n = 4
* coords6: ( 18, 30, 42, 54 }
* n = 2
* coords7: ( 28, 50, 52, 74 }
* Done!
*/