Date: Sat, 22 Mar 2025 15:59:40 +0000
Vaibhav Parate wrote:
> I'd like to propose a *with* block for C++ that allows extending the scope
> of objects, making field access easier and reducing redundant qualifiers.
It is interesting to compare this with what is possible with namespaces:
namespace N {
void foo();
};
void f()
{
N::foo();
}
void g()
{
using namespace N;
foo();
}
Versus classes / structs:
struct S {
void foo();
static void blah();
};
void f()
{
S::blah();
S s;
s.foo();
}
void g()
{
// None of this works:
{
using struct S;
blah();
}
{
S s;
using s;
foo();
}
}
There are certainly situations where I would have found this useful.
One case is a
"graphics context" type:
class GraphicsContext
{
public:
void move_to(Point p);
void line_to(Point p);
// ....
};
If I inherit the GraphicsContext, I can write concisely:
class Spirograph: public GraphicsContext
{
void draw()
{
move_to(a);
draw_to(b);
// In here, I can almost imagine that these are global free functions.
// In fact, in some such APIs these things actually are free
functions and
// the "current graphics context" is a (thread-local?) global.
}
};
but if I want to use a GraphicsContext without inheriting from it, I
need to
qualify everything:
void draw_spirograph(GraphixContext& ctx)
{
ctx.move_to(a);
ctx.draw_to(b);
......
}
On a number of occasions I have had to tediously convert one style to
the other.
Broadly I would say this would be a useful thing to have. On the other hand,
I bet it has been proposed and rejected previously - it's certainly not
a new idea,
I remember using it in Pascal in the 1980s; core language changes that "only
serve to save a few keystrokes" are hardly worth proposing.
Regards, Phil.
> I'd like to propose a *with* block for C++ that allows extending the scope
> of objects, making field access easier and reducing redundant qualifiers.
It is interesting to compare this with what is possible with namespaces:
namespace N {
void foo();
};
void f()
{
N::foo();
}
void g()
{
using namespace N;
foo();
}
Versus classes / structs:
struct S {
void foo();
static void blah();
};
void f()
{
S::blah();
S s;
s.foo();
}
void g()
{
// None of this works:
{
using struct S;
blah();
}
{
S s;
using s;
foo();
}
}
There are certainly situations where I would have found this useful.
One case is a
"graphics context" type:
class GraphicsContext
{
public:
void move_to(Point p);
void line_to(Point p);
// ....
};
If I inherit the GraphicsContext, I can write concisely:
class Spirograph: public GraphicsContext
{
void draw()
{
move_to(a);
draw_to(b);
// In here, I can almost imagine that these are global free functions.
// In fact, in some such APIs these things actually are free
functions and
// the "current graphics context" is a (thread-local?) global.
}
};
but if I want to use a GraphicsContext without inheriting from it, I
need to
qualify everything:
void draw_spirograph(GraphixContext& ctx)
{
ctx.move_to(a);
ctx.draw_to(b);
......
}
On a number of occasions I have had to tediously convert one style to
the other.
Broadly I would say this would be a useful thing to have. On the other hand,
I bet it has been proposed and rejected previously - it's certainly not
a new idea,
I remember using it in Pascal in the 1980s; core language changes that "only
serve to save a few keystrokes" are hardly worth proposing.
Regards, Phil.
Received on 2025-03-22 15:59:44