#include <type_traits>
#include <list>
#include <string>

template <typename T, typename C>
class tl2;

template <typename D, typename T>
class tl1
{
private:
  std::list<T> mTs;
  tl1()
  {
    static_assert(std::is_base_of<tl2<T, D>, T>::value,
                  "T should     inherit from tl2");
  }
  friend D;

public:
  T& getTbyName() const;
};

template <typename T, typename C>
class tl2
{
public:
  tl2()
  {
    static_assert(std::is_base_of<tl1<C, T>, C>::value,
                  "C should inherit from tl1");
  }

  std::string getName()
  {
    return mName;
  }

private:
  std::string mName;
};

class cl1;

class cl2 : public tl2<cl2, cl1>
{
  cl2(){}
};
class cl1 : public tl1<cl1, cl2>
{
  cl1(){}
};

int main()
{
}
