#include <iostream>
#include <memory>
#include <set>

struct Person {
    std::string name;
    std::string address;
    
    Person( std::string n, std::string a ) : name( std::move(n) ), address( std::move(a) ) {}
};

using PersonPtr = std::shared_ptr<Person>;

struct CmpName {
	using is_transparent = void;
	
    bool operator()( const PersonPtr &p1, const PersonPtr &p2 ) const { return p1->name < p2->name; }
    bool operator()( const std::string &s, const PersonPtr &p2 ) const { return s < p2->name; }
    bool operator()( const PersonPtr &p1, const std::string &s ) const { return p1->name < s; }
};

int main() {
    std::set<PersonPtr,CmpName> byName;
    
    byName.insert( std::make_shared<Person>( "John", "Earth" ) );
    auto f = byName.find( "John" );
    if( f != byName.end() ) std::cout << "found " << (*f)->name << std::endl;
    
};