The C++11/14 standards state the following in note 14.7.2/12 [temp.explicit]:
The usual access checking rules do not apply to names used to specify
explicit instantiations. [ Note: In particular, the template arguments
and names used in the function declarator (including parameter types,
return types and exception speci?cations) may be private types or objects
which would normally not be accessible and the template may be a member
template or member function which would not normally be accessible. — end note ]
I would expect to be allowed to use a template if I can instantiate it.
I tried with gcc-4.8.2 and I get the expected behaviour when I access private members of explicitly named classes. However, the access checking rules do apply when I access private members through template parameters. Is this a bug in gcc, or am I missing something?
In the code below, the only difference between 'succeeds' and 'fails' is that the former accesses the private member directly via 'A', while the latter accesses it via the template parameter 'T'. The compiler complains that privateFoobar is private in that context.
#include <iostream>
#include <string>
struct A
{
private:
std::string privateFoobar() {return "private foobar!";}
};
typedef std::string (A::*Foobar)();
template <class Type, Type value>
struct Access
{
static Type getValue() {return value;}
};
template <class T>
struct IndirectAccess
{
static Foobar succeeds() {return Access<Foobar, &A::privateFoobar>::getValue();}
static Foobar fails() {return Access<Foobar, &T::privateFoobar>::getValue();}
};
template class Access<Foobar, &A::privateFoobar>;
int main() {
std::cout << (A().*Access<Foobar,&A::privateFoobar>::getValue())() << std::endl;
std::cout << (A().*IndirectAccess<A>::succeeds())() << std::endl;
std::cout << (A().*IndirectAccess<A>::fails())() << std::endl;
}
In case you are wondering what is the use case for such a sackable offence: creating a framework that would automate the configuration of an application based on implementation choices for the selected components.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…