сделать аргумент функции по умолчанию для окружающей области

Учитывая следующий код/схему, представленную ниже, возможно ли как-то опустить необходимость указывать this?

Есть ли способ изменить код, чтобы функция/конструктор автоматически получал окружающую область видимости, возможно, даже в качестве аргумента шаблона?

#include <iostream>

class AttrBase{
public:
  virtual int g()const = 0;
};

class ABase{
public:
 void reg(const char* name, AttrBase* att){
  std::cout << name << ": " << att->g()<< std::endl;
 }
};


class Attr : public AttrBase{
public: 
  Attr(const char* name, int val, ABase* parent /* = this */) // something like this
   :v(val)
  { 
    parent->reg(name, this);
  };
  int g()const override{return  v;};
  int v;
};


class D:public ABase{
  Attr a{"a", 1, this};
  Attr b{"b", 2, this};
  Attr c{"c", 3};    //< is this somehow possible
};

int main(){
 D d;
}

person vlad_tepesch    schedule 18.12.2019    source источник
comment
Какова цель регистрации атрибутов в базовом классе того класса, членом которого они являются?   -  person Michael Kenzel    schedule 18.12.2019
comment
Добавьте защищенный метод в ABase: Attr MakeAttr(const char* name, int val) { return Attr(name, val, this); }. В D вы пишете Attr a{ MakeAttr("a", 1) };   -  person Raymond Chen    schedule 18.12.2019
comment
@MichaelKenzel Это неясно из вопроса, но я подозреваю, что идея здесь состоит в том, чтобы сделать возможным доступ к членам, используя строковые представления имени. Если это на самом деле хорошая идея, это другой вопрос.   -  person super    schedule 18.12.2019


Ответы (1)


Вы можете добавить функцию-член в ABase, которая создаст для вас Attr.

class ABase{
public:
    void reg(const char* name, AttrBase* att) {
        std::cout << name << ": " << att->g()<< std::endl;
    }

protected:
    template <typename AttrType, typename... Args>
    AttrType make(Args&&... args) {
        return AttrType{std::forward<Args>(args)..., this};
    }
};

Тогда мы можем использовать его как

class D:public ABase {
    Attr a = make<Attr>("a", 1);
    auto b = make<Attr>("b", 2); // works with auto to avoid specifying the type twice
};
person super    schedule 18.12.2019