Monday Sep 17, 2012

C++11 Tidbits: access control under SFINAE conditions

Lately I have been spending quite some time on the SFINAE ("Substitution failure is not an error") features of C++, fixing and tweaking various bits of the GCC implementation.

An important missing piece was the implementation of the resolution of DR 1170 which, in a nutshell, mandates that access checking is done as part of the substitution process. Consider:

class C {
  typedef int type;
};

template <class T, class = typename T::type>
auto f(int) -> char;

template <class>
auto f(...) -> char (&)[2];

static_assert (sizeof(f<C>(0)) == 2, "Ouch");

According to the resolution, the static_assert should not fire, and the snippet should compile successfully, the reason being that the first f overload must be removed from the candidate set because C::type is private to C. On the other hand, before the resolution of DR 1170, the expected behavior was for the first overload to remain in the candidate set, win over the second one, to eventually lead to an access control error (*).

In GCC mainline (would be 4.8) the DR is finally implemented, thus benefiting the many modern programming techniques exploiting SFINAE, among which certainly the GNU C++ runtime library itself, which relies on it for the internals of <type_traits> and in several other places.

Note that the resolution of the DR is active even in C++98 mode, not just in C++11 mode, because it turned out that the traditional behavior, as implemented in GCC, wasn't fully consistent in all the possible circumstances.

(*) In practice, GCC didn't really implement this, the static_assert triggered instead.

About

C++ enthusiasts only, please! ;)

Search

Categories
  • Oracle
Archives
« September 2012
SunMonTueWedThuFriSat
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18
19
20
21
22
23
24
25
26
27
28
29
30
      
Today