Javascript (как браузер, так и NodeJS) имеют встроенный объект JSON
. На этом объекте есть два удобных метода для работы с JSON
. Они следующие:
JSON.parse()
Принимает JSON
в качестве аргумента, возвращает объект JS JSON.stringify()
Принимает объект JS в качестве аргумента возвращает объект JSON
Кроме того, для очень удобного использования JSON
они могут использоваться для других средств. Комбинация обоих методов JSON
позволяет нам очень легко сделать глубокие клоны массивов или объектов. Например:
let arr1 = [1, 2, [3 ,4]];
let newArr = arr1.slice();
arr1[2][0] = 'changed';
console.log(newArr); // not a deep clone
let arr2 = [1, 2, [3 ,4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));
arr2[2][0] = 'changed';
console.log(newArrDeepclone); // A deep clone, values unchanged
Как кто-то еще упомянул, C++ 0x встраивал это в язык. До тех пор я рекомендовал бы Bjarne Stroustrup предложения для шаблонных ограничений .
Редактирование: Повышение также имеет альтернатива для его собственного .
Edit2: Похож , понятия были удалены из C++ 0x .
Можно поместить защитный тип на IFoo, который ничего не делает, удостоверьтесь, что это находится там на T в Нечто:
class IFoo
{
public:
typedef int IsDerivedFromIFoo;
};
template <typename T>
class Foo<T>
{
typedef typename T::IsDerivedFromIFoo IFooGuard;
}
"Неявно" корректный ответ. Шаблоны эффективно создают "утку, вводящую" сценарий, из-за пути, которым они компилируются. Можно вызвать любые функции, которые Вы хотите на введенное шаблоном значение, и единственные инстанцирования, которые будут приняты, являются теми, для которых определяется тот метод. Например:
template <class T>
int compute_length(T *value)
{
return value->length();
}
Мы можем назвать этот метод на указателе на любой тип, который объявляет length()
метод возвращаться int
. Таким образом:
string s = "test";
vector<int> vec;
int i = 0;
compute_length(&s);
compute_length(&vec);
..., но не на указателе на тип, который делает не , объявляют length()
:
compute_length(&i);
Этот третий пример не скомпилирует.
Это работает, потому что C++ компилирует новую версию функции templatized (или класс) для каждого инстанцирования. Поскольку это выполняет ту компиляцию, это делает прямую, почти подобную макросу замену из шаблонного инстанцирования в код до проверки типа. Если все все еще работает с тем шаблоном, то доходы компиляции и мы в конечном счете прибываем в результат. Если что-нибудь перестало работать (как int*
не объявление length()
), то мы получаем страшную шаблонную ошибку времени компиляции на шесть страниц.
Выезд Повышение
Библиотека проверки понятия повышения (BCCL)
библиотека Concept Check позволяет добавлять явный оператор и проверку понятия в стиле предложенное расширение языка C++ .
Вид. Если Вы static_cast к IFoo*, то будет невозможно инстанцировать шаблона, если вызывающая сторона не передаст класс, который может быть присвоен IFoo *.
Только неявно.
Любой метод Вы используете в методе, который на самом деле называют, наложен на шаблонный параметр.
Можно сделать это. Создайте основной шаблон. Заставьте его иметь только Частных конструкторов. Тогда создайте специализации для каждого случая, который Вы хотите позволить (или сделать противоположное, если запрещенный список является значительно уменьшенным, чем позволенный список).
компилятор не позволит Вам инстанцировать шаблонов, которые используют версию с частными конструкторами.
Этот пример только позволяют инстанцирование с интервалом и плавание.
template<class t> class FOO { private: FOO(){}};
template<> class FOO<int>{public: FOO(){}};
template<> class FOO<float>{public: FOO(){}};
не короткий и изящный способ сделать его, но его возможное.
Посмотрите на шаблон CRTP (Любопытно Рекурсивный Шаблонный Шаблон). Это разработано для помогания поддержать статического наследования.