Date: Thu, 6 Jan 2022 13:28:28 +0900
I would like to propose new separator for arguments as shown below:
void func(int a; int b); // not "," but ";"
The motivation to add this feature is that multidimensional subscript
operator in P2128R3 (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2128r3.pdf ) may
cause confusion.
If subscript operator could take multiple arguments, there could be two
types of usages.
The first usage is multidimensional access as explained in P2128R3 and the
second one is subrange access as follows:
class MyVector {
std::vector<int> vec;
public:
MyVector(std::vector<int>&& v) : vec(std::move(v)) {}
MyVector operator[](int a, int b) const { // returns subrange
auto it = vec.begin();
return MyVector(std::vector<int>(it + a, it + b));
}
};
I think this is confusing and probably occurs many bugs.
Thus, to make it clear at a glance will help avoiding bugs.
My proposal is to rule implicitly that array[0, 1] should be a subrange
access and array[0; 1] implies multidimensional access.
Then we can write as follows:
struct Matrix {
float** m;
Matrix operator[](int row_begin, int row_end;
int col_begin, int col_end) const {
Matrix mat{.m = new float*[row_end - row_begin]};
for (int i = row_begin; i < row_end; i++) {
auto& dst = mat.m[i - row_begin];
dst = new float[col_end - col_begin];
std::copy(m[i] + col_begin, m[i] + col_end, dst);
}
return mat;
}
};
void func(const Matrix& mat) {
// cut out 4 elements [1,4], [1,5], [2,4] and [2,5] from mat
Matrix m = mat[1, 3; 4, 6];
}
And this proposal also solve the problem of multiple variadic template
parameters.
template<typename... T, typename... U>
void f1(T... t, U... u); // error: Currently, we cannot do this without
std::tuple
template<typename... T, typename... U>
void f2(T... t; U... u); // OK
f2(1, 2.0; 3.f, 4L); // f2(int, double; float, long)
f2(1; 2.0, 3.f, 4L); // f2(int; double, float, long) different signature
from above
f2( ; ); // this is also OK. f2(void; void)
f2(); // error: no matching function for f2(void)
I am also thinking about variadic arguments with the new separator.
template<typename... T>
void f3(T t;...);
f3(1; 2; 3); // f3(int; int; int)
template<typename... T, typename... U>
void f4(T t, U u;...);
f4(1, 2; 3, 4; 5, 6); // f4(int, int; int, int; int, int)
template<typename... T>
void f5(T... t;...);
f5(1, 2, 3; 4, 5; 6); // f5(int, int, int; int, int; int)
f5(1, 2, 3; ; ); // f5(int, int, int; void; void)
Regards,
Yanagita Tatsuya
hemogurobin.711_at_[hidden]
void func(int a; int b); // not "," but ";"
The motivation to add this feature is that multidimensional subscript
operator in P2128R3 (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2128r3.pdf ) may
cause confusion.
If subscript operator could take multiple arguments, there could be two
types of usages.
The first usage is multidimensional access as explained in P2128R3 and the
second one is subrange access as follows:
class MyVector {
std::vector<int> vec;
public:
MyVector(std::vector<int>&& v) : vec(std::move(v)) {}
MyVector operator[](int a, int b) const { // returns subrange
auto it = vec.begin();
return MyVector(std::vector<int>(it + a, it + b));
}
};
I think this is confusing and probably occurs many bugs.
Thus, to make it clear at a glance will help avoiding bugs.
My proposal is to rule implicitly that array[0, 1] should be a subrange
access and array[0; 1] implies multidimensional access.
Then we can write as follows:
struct Matrix {
float** m;
Matrix operator[](int row_begin, int row_end;
int col_begin, int col_end) const {
Matrix mat{.m = new float*[row_end - row_begin]};
for (int i = row_begin; i < row_end; i++) {
auto& dst = mat.m[i - row_begin];
dst = new float[col_end - col_begin];
std::copy(m[i] + col_begin, m[i] + col_end, dst);
}
return mat;
}
};
void func(const Matrix& mat) {
// cut out 4 elements [1,4], [1,5], [2,4] and [2,5] from mat
Matrix m = mat[1, 3; 4, 6];
}
And this proposal also solve the problem of multiple variadic template
parameters.
template<typename... T, typename... U>
void f1(T... t, U... u); // error: Currently, we cannot do this without
std::tuple
template<typename... T, typename... U>
void f2(T... t; U... u); // OK
f2(1, 2.0; 3.f, 4L); // f2(int, double; float, long)
f2(1; 2.0, 3.f, 4L); // f2(int; double, float, long) different signature
from above
f2( ; ); // this is also OK. f2(void; void)
f2(); // error: no matching function for f2(void)
I am also thinking about variadic arguments with the new separator.
template<typename... T>
void f3(T t;...);
f3(1; 2; 3); // f3(int; int; int)
template<typename... T, typename... U>
void f4(T t, U u;...);
f4(1, 2; 3, 4; 5, 6); // f4(int, int; int, int; int, int)
template<typename... T>
void f5(T... t;...);
f5(1, 2, 3; 4, 5; 6); // f5(int, int, int; int, int; int)
f5(1, 2, 3; ; ); // f5(int, int, int; void; void)
Regards,
Yanagita Tatsuya
hemogurobin.711_at_[hidden]
Received on 2022-01-05 22:28:42