Мой настоящий пример довольно большой, поэтому я буду использовать упрощенный. Предположим, у меня есть тип данных для прямоугольника:Унифицировать C++ шаблоны для указателей, значений и интеллектуальных указателей
struct Rectangle {
int width;
int height;
int computeArea() {
return width * height;
}
}
И еще один тип, который потребляет этот тип, например:
struct TwoRectangles {
Rectangle a;
Rectangle b;
int computeArea() {
// Ignore case where they overlap for the sake of argument!
return a.computeArea() + b.computeArea();
}
};
Теперь, я не хочу ставить ограничения собственности на пользователей TwoRectangles
, так что я хотел бы сделать это шаблон:
template<typename T>
struct TwoRectangles {
T a;
T b;
int computeArea() {
// Ignore case where they overlap for the sake of argument!
return a.computeArea() + b.computeArea();
}
};
Usages:
TwoRectangles<Rectangle> x;
TwoRectangles<Rectangle*> y;
TwoRectangles<std::shared_ptr<Rectangle>> z;
// etc...
Проблема заключается в том, что если абонент хочет использовать указатели, тело функции должно быть разным:
template<typename T>
struct TwoRectangles {
T a;
T b;
int computeArea() {
assert(a && b);
return a->computeArea() + b->computeArea();
}
};
Каков наилучшим способ унифицировать мою шаблонную функцию так, чтобы maxiumum количества коды повторно используется для указателей, значений и интеллектуальных указателей?
Вы можете написать кучу перегрузок с помощью SFINAE, чтобы исключить неприменимые. Или вы можете изменить свой дизайн, чтобы иметь дело только с теми вещами, которые вам нужны, и не оставлять вещи, которые, как вы себе представляете, вам понадобятся, пока вы им не понадобятся. –
Используйте только '->'. Обменивайте значения без указателя в пользовательские объекты, подобные указателям. –
Вы можете сделать то, что стандартная библиотека, и дать ему дополнительный тип шаблона, который является признаком, который знает «как взять' T' и вызвать 'computeArea' на нем». Или просто не переусердствуйте. :) – GManNickG