cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
91 stars 0 forks source link

Дополнить шаблон класса необязятельным списком привязки полей и методов специализирующего шаблон класса к параметрам шаблона #602

Open AlekTananykin opened 3 days ago

AlekTananykin commented 3 days ago

Template binding list

Потребность в такой возможности появлялась при написании разных обработчиков объектов, которые обрабатывали одним и тем же алгоритмом разные параметры одного и того же объекта.

Недавно снова была необходимость в такой возможности в GUI отображения товаров. При этом у одних и тех же товаров нужно было выводить разные характеристики.

Ниже привожу набросок кода, как бы я хотел это сделать, если бы была возможность привязывать методы и поля специализирующего шаблон класса.

include

include

//declare template and add binding to methods and fields tamplate <class {T::ShowValue, T::RightColumnValue}> class GoonessGui { public: void Show(T item) { ... ShowItem(item.ShowValue()); RightColumnValueShow(item.RightColumnValue()); //ShowItem and RightColumnValueShow are internal methods ... }

...

};

class Stove { public: std::string GetStoveCompany() { return _name; }

std::string GetStoveModel()
{
    return _model;
}

std::size_t GetServiceLife()
{
    return _serviceLife;
}

...

};

int main() { Stove someStove;

//use template binding list
GoonessGui<Stove::GetStoveCompany, Stove::GetServiceLife> companiesGui();
companiesGui.Show(someStove); //show stove company

GoonessGui<Stove::GetStoveModel, Stove::GetServiceLife> modelsGui();
modelsGui.Show(someStove); //show stove model

//Do not use template binding list
std::list<Stove> stoveList;//This template forrm is correct too

... 

return 0;

}

Важно чтобы сигнатуры методов и полей пареметров шаблона совпадали с соответствующими сигнатурами специализирующих классов.

Кроме того, такая возможность может возникнуть, если неожиданно возникла необходимость обрабатывать одинаковым образом объекты совершенно разных и несвязанных друг с другом классов.

include

//declare template and add binding to methods and fields tamplate <class {T::ShowValue}> class NetSender { public: void Send(T item) { ... SendItem(item.ShowValue()); //SendItem is an internal method ... }

...

};

class Stove { public:

std::size_t GetStoveName()
{
    return _serviceLife;
}

...

};

class MyFile { public:

std::size_t GetFileName()
{
    return _serviceLife;
}

...

};

int main() { Stove someStove; File someFile;

NetSender<Stove::GetStoveName> stoveNetSender;

companiesGui.Send(someStove); //show stove company

NetSender<File::GetFileName> fileNetSender;
fileNetSender.Send(someFile); //show stove model

... 

return 0;

}

И наконец вариадик

//Variadic example

include

//declare template and add binding to methods and fields tamplate <class ...{T::ShowValue}> class Packer { public: void Add(T ... item) { ...

    ...
}

...

};

class Stove { public:

std::size_t GetStoveName()
{
    return _serviceLife;
}

...

};

class MyFile { public:

std::size_t GetFileName()
{
    return _serviceLife;
}

...

};

int main() { Stove someStove; File someFile;

Packer<Stove::GetStoveName, MyFile::GetFileName> packer;

packer.Add(someStove, someFile); 

... 

return 0;

}

Полезные ссылки: