Problem with SFINAE in Ideone?

I am trying to debug the problem I am getting with Visual Studio comparing the Visual Studio output to the GCC output, but I cannot get an extremely simplified version of the code to compile in Ideone

#include <exception>
#include <iostream>

template <int x>
struct foo {};

template <>
struct foo<0> { using type = int; };

template <typename Foo>
struct bar
    bar(void) {}

    template <typename = typename Foo::type>
    bar(const bar &) {}

int main(void)
    bar<foo<1>> x;


The above is giving me an error when I try to run it using Ideone:

prog.cpp: In instantiation ofstruct bar<foo<1> >’:
prog.cpp:21:17:   required from here
prog.cpp:16:5: error: no type namedtypeinstruct foo<1>’
     bar(const bar &) {}


In my opinion, failure to replace Foo::type

should not result in a compilation error. Note that creating a copy constructor bar(const bar &) { typename Foo::type x; }

makes the program easy to compile. I am trying to use this pattern in pretty much the same way as it is used std::enable_if

, which also leads to compilation errors when used anywhere in the class, not just in the copy constructor. Is this the correct behavior? I'm pretty sure that's not the case, but I always thought Ideone was using GCC in the background ...


source to share

1 answer

Yes, this is the correct behavior.

SFINAE applies when inferring template parameters during function template overload resolution (the compiler is allowed to drop specialization without error).

In your case, the error did not occur during overload resolution, but during template creation: the template bar

simply cannot be created because the copy constructor requires a nested type Foo::type

, which does not exist when the template parameter is foo<1>


In the latter case, if you state:

template <typename Foo>
struct bar
    bar(void) {}

    bar(const bar &) { typename Foo::type x; }


It compiles until you call the copy constructor. Using the copy constructor will result in the same compilation error:

bar<foo<1>> x2 = x; // Error




All Articles