#include <iostream>
#include <set>
#include <string>
#include <type_traits>
using namespace std;

struct base 
{ 
    struct compare 
    {
        template <typename T, std::enable_if_t<!std::is_base_of<base, T>::value, bool> = true>
        bool operator()(const T& lhs, const base& rhs) const { return lhs < rhs.Name; }
        
        template <typename T, std::enable_if_t<!std::is_base_of<base, T>::value, bool> = true>
        bool operator()(const base& lhs, const T& rhs) const { return lhs.Name < rhs; }

        bool operator()(const base& lhs, const base& rhs) const { return lhs.Name < rhs.Name; } 

        using is_transparent = int; 
    }; 

    /*explicit base(const char * name) : Name(name) {} */
    explicit base(std::string name) : Name(std::move(name)) {}
    
    virtual ~base() {};

    std::string Name;
};
/*
base::~base()
{
}
*/
struct derived : base
{ 
        explicit derived(const std::string& name) 
                : base(name) 
        { 
        } 
};

int main() 
{ 
    std::set<derived, base::compare> baseset; 

    baseset.emplace("Test"); 

    auto x = baseset.find("Test"); 

    std::cout << (x != baseset.end() ? x->Name : "not found!") << std::endl;
    
    auto y = baseset.find(string("Test2"));
    
    std::cout << (y != baseset.end() ? y->Name : "not found!") << std::endl;
}
