Я почти уверен, что вы не можете использовать значения параметров по умолчанию в JS, вот что, вероятно, ломает в IE.
Вместо этого вам нужно будет установить его по умолчанию:
processMessages: function(problem, container, useMessage) {
if (typeof useMessage === 'undefined') useMessage = true;
}
То, что Вы в конечном счете хотите, я думаю, должно сделать, чтобы пользователь ввел
Vector<T, N>
И в зависимости от N
, пользователь получит небольшие разные вещи. Первое не выполнит это, но второе желание, на цене дублирования кода.
То, что можно сделать, должно инвертировать наследование:
template<typename T, size_t N> struct VectorBase
{
};
template<typename T> struct VectorBase<T, 2>
{
};
template<typename T> struct VectorBase<T, 3>
{
};
template<typename T, size_t N> struct Vector : VectorBase<T, N>
{
};
И реализуйте несколько функций, которые зависят только от N, являющегося некоторым определенным значением в соответствующем базовом классе. Можно добавить защищенный деструктор в них, для предотвращения пользователей, удаляющих экземпляры Vector
через указатели на VectorBase
(обычно они даже не должны мочь назвать VectorBase
: Поместите те основания в некоторое пространство имен реализации, как detail
).
Другая идея состоит в том, чтобы объединить это решение с тем, упомянутым в другом ответе. Наследуйтесь конфиденциально (вместо публично как выше) и добавьте функции обертки в производный класс, которые называют реализации базового класса.
Еще одна идея состоит в том, чтобы использовать всего один класс и затем enable_if
(использование boost::enable_if
) включить или отключить их для конкретных значений N
, или используйте преобразователь интервала к типу как это, которое является большим количеством simplier
struct anyi { };
template<size_t N> struct i2t : anyi { };
template<typename T, size_t N> struct Vector
{
// forward to the "real" function
void some_special_function() { some_special_function(i2t<N>()); }
private:
// case for N == 2
void some_special_function(i2t<2>) {
...
}
// case for N == 3
void some_special_function(i2t<3>) {
...
}
// general case
void some_special_function(anyi) {
...
}
};
Тем путем это абсолютно очевидно для пользователя Vector
. Это также не добавит пространства наверху для компиляторов, делающих пустую (довольно распространенную) оптимизацию базового класса.
Используйте наследование и частное наследование. И не используйте виртуальные функции. С тех пор с частным наследованием, Вы не имеете, - a, никто не сможет использовать указатель базового класса на полученный подкласс, и Вы не получите режущую проблему когда passinfg значением.
Это дает Вам лучший из обоих миров (и действительно это - как большинство библиотек реализует многие классы STL).
Из http://www.hackcraft.net/cpp/templateInheritance/ (обсуждающий станд.:: вектор, не Ваш Векторный класс):
vector<T*>
как объявляют, имеет частную основуvector<void*>
. Все функции, которые помещают новый элемент в вектор, такой какpush_back()
, вызовите эквивалентную функцию на этой частной основе, поэтому внутренне нашvector<T*>
использует avector<void*>
для устройства хранения данных. Все функции, которые возвращают элемент из вектора, такой какfront()
, выполните astatic_cast
на результате вызывания эквивалентной функции на частной основе. Начиная с единственного способа получить указатель вvector<void*>
(кроме сознательно опасных приемов), через интерфейс, предлагаемыйvector<T*>
безопасно статично броситьvoid*
назад кT*
(илиvoid*&
назад кT*&
, и так далее).
В целом, если STL делает это как это, это походит на достойный образец для подражания.
При использовании шаблонной специализации слишком много, вероятно, необходимо заново продумать дизайн. Рассмотрение, что Вы скрываете его позади a typedef
, Я сомневаюсь, что Вам нужен он.
Наследование следует использовать только для моделирования "is-a". Специализация была бы более чистой альтернативой. Если вам нужно или вы хотите использовать наследование по какой-либо причине, по крайней мере сделайте его частным или защищенным наследованием, чтобы вы не наследовали публично от класса с общедоступным невиртуальным деструктором.
Да, ребята из метапрограммирования шаблонов всегда выполняются
struct something : something_else {};
Но эти something
являются метафункциями и не предназначены для использования в качестве типов.