Topic: Private access in partial specialization definitions


Author: maowfijwef@amfoijefa.ca
Date: Fri, 14 Dec 2012 09:20:41 -0800 (PST)
Raw View
GCC's behavior differs from Clang and Visual C++ in the following examples:

#include<type_traits>

template<typename T, typename Enabler = void>
struct test1 : std::false_type {};

template<typename T>
struct test1<T, typename T::typedef_test>  : std::true_type {};

template<typename T, typename Enabler = void>
struct test2 : std::false_type {};

template<typename T>
struct test2<T,
     typename std::enable_if<
         T::enum_test,
         void
     >::type>  : std::true_type {};

struct object
{
     template<typename T, typename Enabler>
     friend struct test1;

     template<typename T, typename Enabler>
     friend struct test2;

     private:
         enum { enum_test = true };
         typedef void typedef_test;
};

// test1
static_assert(test1<object>::value, "failed");

// test2
static_assert(test2<object>::value, "failed");

Results (compiler, test1, test2):
g++ (4.7.2), pass, fail
g++ (4.8.0), fail, fail
clang++ (3.3), pass, pass
Visual C++ 2012, pass, pass

Which is correct?  I'd appreciate direction to the relevant sections of
the standard if at all possible.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- 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: Sat, 15 Dec 2012 10:53:09 -0800 (PST)
Raw View
Am 14.12.2012 18:20, schrieb maowfijwef@amfoijefa.ca:
> GCC's behavior differs from Clang and Visual C++ in the following examples:
>
> #include<type_traits>
>
> template<typename T, typename Enabler = void>
> struct test1 : std::false_type {};
>
> template<typename T>
> struct test1<T, typename T::typedef_test>  : std::true_type {};
>
> template<typename T, typename Enabler = void>
> struct test2 : std::false_type {};
>
> template<typename T>
> struct test2<T,
>       typename std::enable_if<
>           T::enum_test,
>           void
>       >::type>  : std::true_type {};
>
> struct object
> {
>       template<typename T, typename Enabler>
>       friend struct test1;
>
>       template<typename T, typename Enabler>
>       friend struct test2;
>
>       private:
>           enum { enum_test = true };
>           typedef void typedef_test;
> };
>
> // test1
> static_assert(test1<object>::value, "failed");
>
> // test2
> static_assert(test2<object>::value, "failed");
>
> Results (compiler, test1, test2):
> g++ (4.7.2), pass, fail
> g++ (4.8.0), fail, fail
> clang++ (3.3), pass, pass
> Visual C++ 2012, pass, pass
>
> Which is correct?  I'd appreciate direction to the relevant sections of
> the standard if at all possible.

With the resolution of the issue

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#580

the code should be well-formed. It looks to me as if gcc hasn't yet
applied the resolution. I suggest to open a compiler bug for this.

HTH & Greetings from Bremen,

Daniel Kr   gler




--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]