Topic: auto leaks private types
Author: Marius Stoica <letto2@gmail.com>
Date: Sun, 20 Jun 2010 14:49:39 CST Raw View
Hi,
I've come across an undesired behaviour of auto
This happens with GCC 4.4
class Size {
enum class ESize {
small, large
};
ESize value;
public :
static const ESize
small = ESize::small,
large = ESize::large;
Size(ESize a):value{a}{}
};
//..
Size a = Size::small; // ok
// Error: Size::ESize x = Size::small;
auto b = Size::small;// ??? i'd like this to be a Size;
typedef decltype(b) ESize; // ??
comments?
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 21 Jun 2010 00:23:39 CST Raw View
On 20 Jun., 22:49, Marius Stoica <let...@gmail.com> wrote:
> I've come across an undesired behaviour of auto
> This happens with GCC 4.4
>
> class Size {
> enum class ESize {
> small, large};
>
> ESize value;
> public :
> static const ESize
> small = ESize::small,
> large = ESize::large;
> Size(ESize a):value{a}{}
> };
>
> //..
>
> Size a = Size::small; // ok
> // Error: Size::ESize x = Size::small;
> auto b = Size::small;// ??? i'd like this to be a Size;
You are misunderstanding auto here. Your comment
implies that you also expect that within
template<class T> void foo(T t) {
static_assert(std::is_same<Size, T>::value, "Ouch");
}
int main() {
foo(Size::small);
}
the assertion would hold, alas, it does not. In fact, auto
behaves very similar to the effect of function templates
that deduce their argument types.
> typedef decltype(b) ESize; // ??
>
> comments?
Another comment in regard to leaking: No, I don't agree
that auto is "leaking" here. Access control in C++ is
*not* access control of types and other entities, but
it is only access control of *names*, see class 11,
[class.access]/1:
"1 A member of a class can be
private; that is, its **name** can be used only by members
and friends of the class in which it is declared. [..]"
(Emphasis mine). This simply means that a function template
can deduce the type of Size::small, even though it could *name*
this type as Size::ESize. The same rules apply to auto and
similarly to decltype. E.g.
typedef decltype(Size::small) TS;
immediately deduces TS as having the same type as
const Size::ESize (again, without being able to name
it as such).
In summary: You are mis-using auto, if you want to
initialize a type T with a source value of type U.
Obviously you need to name the destination type
explicitly, because auto would just allow for the
*same* type as the source value.
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date: Mon, 21 Jun 2010 00:22:37 CST Raw View
* Marius Stoica, on 20.06.2010 22:49:
>
> Hi,
> I've come across an undesired behaviour of auto
> This happens with GCC 4.4
>
> class Size {
> enum class ESize {
> small, large
> };
> ESize value;
> public :
> static const ESize
> small = ESize::small,
> large = ESize::large;
> Size(ESize a):value{a}{}
> };
>
> //..
>
> Size a = Size::small; // ok
> // Error: Size::ESize x = Size::small;
> auto b = Size::small;// ??? i'd like this to be a Size;
> typedef decltype(b) ESize; // ??
>
> comments?
Well, it has been discussed before. Summing up, with 'auto' it's far
*easier* to *inadvertently* leak private types than it was in C++98.
In C++98 it could happen, like
<code>
class Size
{
private:
struct E
{
enum Size { small, large };
};
E::Size value_;
public :
static const E::Size small = E::small;
static const E::Size large = E::large;
Size( E::Size a ): value_( a ) {}
};
template< class T >
void foo( T ) {}
int main()
{
foo( Size::small ); // Private type leaked (or loken?).
}
</code>
But I think it's far too easy with 'auto'.
Cheers,
- Alf
--
blog at <url: http://alfps.wordpress.com>
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Mon, 21 Jun 2010 12:01:52 CST Raw View
On Jun 21, 8:23 am, Daniel Kr=FCgler <daniel.krueg...@googlemail.com>
wrote:
[..]
> This simply means that a function template can deduce the type
> of Size::small, even though it could *name* this type as
^
Somehow an internet demon must have removed the word "not" at
the position marked above ;-)
> Size::ESize. The same rules apply to auto and similarly to
> decltype. E.g.
- Daniel
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]