The code below overrides virtual A::foo()
with B::foo() override
. If the BROKEN
is not defined, then it compiles just fine. My understanding of the std::enable<std::is_pod<Q>::value>::type
shenanigans is that it effectively replaces the SFINAE expression with void
, and this should be identical to plain old void
.
However, it won't compile. I get compiler errors:
Intel compiler (icpc):
$ make a CXXFLAGS="-std=c++11 -DBROKEN"
icpc -std=c++11 -DBROKEN a.cpp -o a
a.cpp(24): error: object of abstract class type "B<int>" is not allowed:
pure virtual function "A::foo" has no overrider
B<int> b;
^
gcc:
$ make a CXXFLAGS="-std=c++11 -DBROKEN" CXX=g++
g++ -std=c++11 -DBROKEN a.cpp -o a
a.cpp: In function ‘int main()’:
a.cpp:24:11: error: cannot declare variable ‘b’ to be of abstract type ‘B<int>’
B<int> b;
^
a.cpp:9:7: note: because the following virtual functions are pure within ‘B<int>’:
class B : A
^
a.cpp:5:16: note: virtual void A::foo()
virtual void foo() = 0;
^
make: *** [a] Error 1
Here is the test case:
#include <type_traits>
class A {
public:
virtual void foo() = 0;
};
template<typename T>
class B : A
{
public:
#ifdef BROKEN
template<class Q = T>
typename std::enable_if<true>::type
#else
void
#endif
foo() override { }
};
int main()
{
B<int> b;
b.foo();
return 0;
}
If I don't use virtual functions, the std::enable<true>
thing works as expected.
addendum
Those results were for gcc 4.8.3. With gcc 5.3, I get one extra line of compiler error:
a.cpp:19:9: error: member template ‘std::enable_if<true>::type B<T>::foo()’ may not have virt-specifiers
foo() override { }
^
Why not?