Re: Reference to void
Alf P. Steinbach wrote:
Let's make the following assumption: every type is implicitly derived
from void. Many C++ programmers can accept that.
Name one. It's manifestly false; it is, in fact, illegal to
derive from void (or from any incomplete type).
Note that Lucian (as I read that article, especially in light of the
rest of it) was describing a future extension, not the current language.
Thank you ... Indeed, I was talking about somthing which is not
implemented in C++.
When discussing a future extension of the language it's hardly an
argument against that extension that it doesn't yet exist. ;-)
However, since 'void' has at least two different meanings (sometimes it
behaves like a type, sometimes like a syntactic placeholder) it's IMO a
poor choice for an 'any' type.
IMHO it's worse to have all kind of exceptions in the language, than to
have one good rule that works in (almost) all cases. In this case, as
you noticed currently "void" isn't really a type, and isn't really a
syntactic placeholder. And the bad thing about this duality is the fact
that we don't know the exact border of this: sometimes void behaves
like a type and we can have pointers to void, and sometimes void
doesn't behave like a type and doesn't allow us to have references of
type void.
Here is an example:
<code>
template <typename T>
struct Test
{
typedef T original_type;
typedef T* pointer_type;
typedef T& reference_type;
};
class A {};
bool b1 = boost::is_same<int, void>::value;
bool b2 = boost::is_same<int, Test<void>::original_type>::value; // (2)
Error here?
bool b3 = boost::is_same<int, Test<A>::original_type>::value;
</code>
Is there something wrong with the definition of the Test class
template? Am I doing something wrong when I try to instantiate
Test<void>, when I need the original type? Why should the creator of
the template have to think of the "void exception" when he is building
his class?
Void, as a type, is an incomplete type, which can never be
completed. And in no case can you derive from an incomplete
type. The rules concerning convertion of T* to void* do NOT
obey the rules of derived to base (which only works if the types
are complete), and of course, work even in cases where
inheritance would be illegal, e.g. int* to void*.
Let's think about what the extension would be used for.
There's not much of a technical problem, for
void& rv = *pv;
would simply be translated, internally, to
typeof(pv)& rv = pv;
(except with C++0x mumbo-jumbo-name for typeof) and
void const& r = SomeExpression();
would be translated, internally, to
typeof(SomeExpression) const& r = SomeExpression;
but in both cases with a restriction on what you could do with the
reference, namely the restriction implied by 'void'.
But what's that restriction good for?
Not very much, I think.
And then why not use the keyword 'auto' instead, to get the compiler's
deduced type instead of the restrictive 'void'?
Indeed, this reference to void ideea doesn't help too much. Again,
let's take a piece of code:
<code>
void f1()
{
auto& obj = f();
// A lot of code folllows...
}
void f2()
{
void& obj = f();
// A lot of code folllows...
}
</code>
If you take the first look in f1() you don't know what happens to the
result of the function call. You may rush to say that obj will be
accessed in the code that follows. But this is not necessarly the
intent. One can only want to extend the scope of the object returned by
function call. IMHO, the second approach is better for this purpose as
the reader is shure that no one will access or change the state of obj
(well... almost).
Best regards,
Lucian Radu Teodorescu
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]