У меня есть дилемма. Предположим, у меня есть класс шаблона:Параметры шаблона dilemma
template <typename ValueT>
class Array
{
public:
typedef ValueT ValueType;
ValueType& GetValue()
{
...
}
};
Теперь я хочу, чтобы определить функцию, которая получает ссылку на класс и вызывает функцию GetValue(). Я обычно рассматривают следующие два способа:
Метод 1:
template <typename ValueType>
void DoGetValue(Array<ValueType>& arr)
{
ValueType value = arr.GetValue();
...
}
Метод 2:
template <typename ArrayType>
void DoGetValue(ArrayType& arr)
{
typename ArrayType::ValueType value = arr.GetValue();
...
}
Там нет почти никакой разницы между этими двумя методами. Даже вызов обеих функций будет выглядеть точно так же:
int main()
{
Array<int> arr;
DoGetValue(arr);
}
Теперь, какая из двух является лучшей? Я могу думать о некоторых минусах и плюсах:
Метод 1 плюсы:
Параметр реальный класс не шаблон, так что легче для пользователя, чтобы понять интерфейс - это очень четко указано, что параметр должен быть массивом. В методе 2 вы можете угадать это только от имени. Мы используем ValueType в функции, поэтому это более ясно, чем когда оно скрыто внутри массива и должно быть доступно с помощью оператора области.
Кроме того, ключевое слово typename может вводить в заблуждение для многих программистов, не имеющих шаблонов.
Метод 2 плюсы:
Эта функция является более "истинным" к своей цели. Когда я думаю, что если это так, мне не нужен класс, чтобы быть Array. Мне действительно нужен класс, который имеет метод GetValue и тип ValueType. Это все. То есть этот метод является более общим.
Этот метод также меньше зависит от изменений в классе Array. Что делать, если параметры шаблона массива изменены? Почему это должно повлиять на DoGetValue? На самом деле неважно, как определяется массив.
Evey time У меня такая ситуация Я не уверен, что выбрать. Каков твой выбор?
В целях обеспечения целостности я бы также рассмотрел возможность «изменения» интерфейса вашего собственного класса и попытаться имитировать контейнеры STL, таким образом вы сможете использовать свой собственный шаблон функций в контейнерах STL в качестве бонуса> 'value_type 'вместо' ValueType', 'front' или' back' вместо 'GetValue' (или, возможно,' at', если он ожидает позицию?) и т. д. –
@Matthieu, хороший момент! Это то, что я должен рассмотреть. Я никогда не думал о возможности мистификации STL. Это действительно полезно и даже дает визуальные подсказки в коде. Благодарю. – FireAphis