I'm working on a project where SFINAE is used to detect whether a member function exists. I'm running into a problem with the following example:
class Base
{
private:
template <class T>
void foo( T t ) {}
void snarf() {}
};
class Derived : public Base
{
public:
template <class T>
void bar( T t )
{
foo( t ); // shouldn't be possible
snarf(); // bug in gcc, correctly identified as error in clang
}
};
The problem seems to be that the access control (e.g. private) in the base class is not being respected in the derived class when trying to access inherited functions. Both foo and snarf should be inaccessible from the derived class. So when I try to test if some derived class has some function, it is incorrectly accessing the base class to find a match.
In g++ 4.8.1, both calling foo and snarf are incorrectly allowed to happen, which I'm pretty sure is an instance of this bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41437
In clang++ 3.3, calling snarf is correctly identified as an error, but foo is allowed to be called, which seems like it should also be an error. Does this look like a bug in clang++? (I've posted a bug report just in case it turns out to be http://llvm.org/bugs/show_bug.cgi?id=16410)
Given that this may well be a bug in both compilers, is there any clever workaround I can use to detect that derived doesn't really have access to foo? The way I'm actually using this is the following:
template <class T, class T2, class Unused = void>
struct has_member_foo : std::false_type {};
Where has_member_foo
is specialized to extend from std::true_type
when calling declval<T&>().foo(declval<T2&>())
resolves to a valid function ala Checking a member exists, possibly in a base class, C++11 version. I need this to fail when a derived class inherits a private version of foo
.