struct foo
{
virtual void bar();
virtual void baz() = &bar;
};
Some questions, I'm just curious:1. are there important differences with the following?struct foo{virtual void bar();virtual void baz() { bar(); } // this is inlined AFAIK, isn't it?};
On 10 July 2013 14:03, Klaim - Joël Lamotte <mjk...@gmail.com> wrote:
Some questions, I'm just curious:1. are there important differences with the following?struct foo{virtual void bar();virtual void baz() { bar(); } // this is inlined AFAIK, isn't it?};Inlined? It's a virtual call.
Inlined? It's a virtual call.
Both of these cost a small amount of code size with current compilers.
The proposed syntax would make it fairly obvious that no extra
function is emitted. However, I believe compilers could optimize
either of the suggested alternatives into a shared vtable entry, and
if the code size improvement is important to someone, they should bug
their compiler vendor to do that. If something in the language
prohibits that optimization, that would be worth fixing.
class ScriptObject
{
virtual void OpCopyAssign( const ScriptObject * );
virtual void OpMoveAssign( ScriptObject * ) = &CopyAssign;};
class ScriptNumber : public ScriptObject
{
// defines only OpCopyAssign}
class ScriptString : public ScriptObject
{
// defines both
};
class ScriptObject
{
virtual void OpCopyAssign( const ScriptObject * );
virtual void OpMoveAssign( ScriptObject *other ) { OpCopyAssign( other ); } // virtual call};
struct foo
{
virtual void bar();
virtual void baz() = &bar;
};This shall mean, that the default implementation for baz() is bar(), unless this
behavior is overridden in a derived class.
bar: foo::bar
baz: foo::bar
bar: goo::bar
baz: foo::bar
bar: goo::bar
baz: hoo::baz
Currently you can achieve something like this with function pointers, but they have certain limitations.
Here's an example of one use I was envisioning:
template <typename T>
void func(int myInt, const char* myStr, bool myBool)
{
T::something(myInt, myStr, myBool);
}
struct thing_i_dont_control
{
static int doIt(int, const char*, bool);
};
// essentially a concept map
struct map_it
{
using something = thing_i_dont_control::doIt;
};
func<map_it>(1, "a", true);
This would be even better if it allowed for parameter reordering and providing defaults.
The examples provided so far have been "simple" functions. When you get functions that take five or six parameters that need to be forwarded, it gets a bit verbose (and I'd argue error prone).
I also have a gut feeling that this type of technique can be used for some interesting dependency injection and mocking scenarios, but I haven't fully developed those ideas.
True, my thoughts have nothing to do with virtual functions, but I believe the ideas presented thus far are similar enough to broaden the discussion.
And apologies for the poor formatting, this was from my mobile.
Not me. I would expect that goo::baz vtable entry is &goo::bar as the declarationis a shortcut for
virtual void baz() = &bar();
virtual void baz() { bar() }
Otherwise I don't see the interest.
Not me. I would expect that goo::baz vtable entry is &goo::bar as the declaration
virtual void baz() = &bar();
is a shortcut for
virtual void baz() { bar() }
Otherwise I don't see the interest.
Vicente
If you interpret it as that, this features has absolute zero value - it is even LONGER to write than what it was shortcut to ("=&x;" vs. "{x}").
However, if you interpret is as defining a vtable entry that points to the very same function, that is different, it might be useful. But as I said, still needs a better usecase.
Think about header files that are published as part of an SDK interface, in anticipation that 3rd party programmers are going to derive from it. With this proposal, it would be possible for the interface author to specify that "baz = &bar", and if a user does not wish to override baz, he gets the reasonable default behavior (i.e. a call to baz will call his *overridden* version of bar) with out the penalty of a double dispatch.