#include <iostream>
using namespace std;
/**
* @brief Defines a passkey for type T.
*/
template < typename ...Ts >
class PassKey
{
private :
// befriend T so that only T can create a PassKey object
friend Ts...;
// make default constructor private so that only T can access it
PassKey( ) { }
// noncopyable, non-assignable so that key can not be re-used
PassKey( const PassKey& ) = delete ;
PassKey& operator= ( const PassKey& ) = delete ;
} ;
struct B;
struct A
{
void doSomething( PassKey< B> ) const
{ }
} ;
struct B
{
void callDoSomething( const A& a) const
{
a.doSomething ( { } ) ;
}
} ;
int main( ) {
A a;
B b;
b.callDoSomething ( a) ;
int FraudKey= 0 ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLyoqCiogQGJyaWVmIERlZmluZXMgYSBwYXNza2V5IGZvciB0eXBlIFQuCiovCnRlbXBsYXRlIDx0eXBlbmFtZSAuLi5Ucz4KY2xhc3MgUGFzc0tleQp7CnByaXZhdGU6CiAgICAvLyBiZWZyaWVuZCBUIHNvIHRoYXQgb25seSBUIGNhbiBjcmVhdGUgYSBQYXNzS2V5IG9iamVjdAogICAgZnJpZW5kIFRzLi4uOwoKICAgIC8vIG1ha2UgZGVmYXVsdCBjb25zdHJ1Y3RvciBwcml2YXRlIHNvIHRoYXQgb25seSBUIGNhbiBhY2Nlc3MgaXQKICAgIFBhc3NLZXkoKSB7fQoKICAgIC8vIG5vbmNvcHlhYmxlLCBub24tYXNzaWduYWJsZSBzbyB0aGF0IGtleSBjYW4gbm90IGJlIHJlLXVzZWQKICAgIFBhc3NLZXkoY29uc3QgUGFzc0tleSYpID0gZGVsZXRlOwogICAgUGFzc0tleSYgb3BlcmF0b3I9KGNvbnN0IFBhc3NLZXkmKSA9IGRlbGV0ZTsKfTsKCnN0cnVjdCBCOwoKc3RydWN0IEEKewoJdm9pZCBkb1NvbWV0aGluZyhQYXNzS2V5PEI+KSBjb25zdAoJe30KfTsKCnN0cnVjdCBCCnsKCXZvaWQgY2FsbERvU29tZXRoaW5nKGNvbnN0IEEmIGEpIGNvbnN0Cgl7CgkJYS5kb1NvbWV0aGluZyh7fSk7Cgl9Cn07CgoKCmludCBtYWluKCkgewoJQSBhOwoJQiBiOwoJYi5jYWxsRG9Tb21ldGhpbmcoYSk7CglpbnQgRnJhdWRLZXk9MDsKCXJldHVybiAwOwp9