Шаблонный ограничительный C++

Резюме:

Javascript (как браузер, так и NodeJS) имеют встроенный объект JSON. На этом объекте есть два удобных метода для работы с JSON. Они следующие:

  1. JSON.parse() Принимает JSON в качестве аргумента, возвращает объект JS
  2. 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

61
задан Leon Timmermans 29 September 2008 в 15:29
поделиться

8 ответов

Как кто-то еще упомянул, C++ 0x встраивал это в язык. До тех пор я рекомендовал бы Bjarne Stroustrup предложения для шаблонных ограничений .

Редактирование: Повышение также имеет альтернатива для его собственного .

Edit2: Похож , понятия были удалены из C++ 0x .

34
ответ дан James Adkison 7 November 2019 в 13:33
поделиться

Можно поместить защитный тип на IFoo, который ничего не делает, удостоверьтесь, что это находится там на T в Нечто:

class IFoo
{
public:
    typedef int IsDerivedFromIFoo;
};

template <typename T>
class Foo<T>
{
    typedef typename T::IsDerivedFromIFoo IFooGuard;
}
14
ответ дан Eclipse 7 November 2019 в 13:33
поделиться

"Неявно" корректный ответ. Шаблоны эффективно создают "утку, вводящую" сценарий, из-за пути, которым они компилируются. Можно вызвать любые функции, которые Вы хотите на введенное шаблоном значение, и единственные инстанцирования, которые будут приняты, являются теми, для которых определяется тот метод. Например:

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()), то мы получаем страшную шаблонную ошибку времени компиляции на шесть страниц.

37
ответ дан Daniel Spiewak 7 November 2019 в 13:33
поделиться

Выезд Повышение

Библиотека проверки понятия повышения (BCCL)

библиотека Concept Check позволяет добавлять явный оператор и проверку понятия в стиле предложенное расширение языка C++ .

8
ответ дан Félix Gagnon-Grenier 7 November 2019 в 13:33
поделиться

Вид. Если Вы static_cast к IFoo*, то будет невозможно инстанцировать шаблона, если вызывающая сторона не передаст класс, который может быть присвоен IFoo *.

2
ответ дан Lou Franco 7 November 2019 в 13:33
поделиться

Только неявно.
Любой метод Вы используете в методе, который на самом деле называют, наложен на шаблонный параметр.

1
ответ дан shoosh 7 November 2019 в 13:33
поделиться

Можно сделать это. Создайте основной шаблон. Заставьте его иметь только Частных конструкторов. Тогда создайте специализации для каждого случая, который Вы хотите позволить (или сделать противоположное, если запрещенный список является значительно уменьшенным, чем позволенный список).

компилятор не позволит Вам инстанцировать шаблонов, которые используют версию с частными конструкторами.

Этот пример только позволяют инстанцирование с интервалом и плавание.

template<class t> class FOO { private: FOO(){}};

template<> class FOO<int>{public: FOO(){}};

template<> class FOO<float>{public: FOO(){}};

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

0
ответ дан Eclipse 7 November 2019 в 13:33
поделиться

Посмотрите на шаблон CRTP (Любопытно Рекурсивный Шаблонный Шаблон). Это разработано для помогания поддержать статического наследования.

-1
ответ дан 7 November 2019 в 13:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: