[cfe-dev] std::enable_if<T::a> with enum T::a = 2

Richard Smith richard at metafoo.co.uk
Thu Sep 13 09:21:36 PDT 2012


Hello,

On Thu, Sep 13, 2012 at 7:31 AM, Ansgar Burchardt <
ansgar.burchardt at iwr.uni-heidelberg.de> wrote:

> Hi,
>
> I'm not sure if this is the right list, but I encountered a problem with
> std::enable_if in clang++:
>
> ---
> #include <iostream>
> #include <type_traits>
>
> template<int n>
> struct A {
>   enum { a = n };
> };
>
> template<class T, typename dummy = void>
> struct B
> {
>   enum { b = 1 };
> };
>
> template<class T>
> struct B<T, typename std::enable_if<T::a>::type>
> {
>   enum { b = 2 };
> };
>
> int main(void)
> {
>   std::cout << B< A<1> >::b << std::endl;
>   std::cout << B< A<2> >::b << std::endl;
> }
> ---
>
> This will give "2 1" with clang 3.1-8 (Debian), but "2 2" with g++
> 4.7.1-8 (Debian).  I'm far from being an expert in C++, but shouldn't
> both lines use the specialized version of B (ie. g++ is correct)?
>

No, this program's behavior changed in C++11. Converting a constant 2 to
bool is a narrowing conversion, which is disallowed in a converted constant
expression such as a non-type template argument. G++ apparently doesn't
implement that rule yet.

The second result should also be '1' in C++11 mode -- this is another
C++11-specific change. I brought this to the committee's attention in
DR1407, and we agreed that this was the desired behavior, but no compiler
has implemented it yet (as far as I'm aware).

Best regards!
Richard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120913/45796b93/attachment.html>


More information about the cfe-dev mailing list