Странная ошибка компиляции, связанная с скобкой шаблона, интерпретируемой как оператор & ldquo; & gt; & rdquo; [Дубликат]

Я бы продолжил ваш подход «преобразовать число в строку». Однако вы поймете, что ваш предложенный алгоритм терпит неудачу, если ваш идентификатор является простым и большим, чем 52 .

Теоретический фон

Вам нужен Bijective Функция f . Это необходимо, чтобы вы могли найти обратную функцию g ('abc') = 123 для функции f (123) = 'abc' . Это означает:

  • Не должно быть x1, x2 (с x1 ≠ x2) , что сделает f (x1) = f (x2) ,
  • , и для каждого y вы должны найти x , чтобы f (x) = y .

Как преобразовать идентификатор в сокращенный URL

  1. Подумайте о алфавите, который мы хотим использовать. В вашем случае это [a-zA-Z0-9]. Он содержит 62 буквы .
  2. Возьмите автоматически сгенерированный уникальный уникальный ключ (например, с помощью auto-incremented id таблицы MySQL). В этом примере я буду использовать 12510 (125 с базой 10).
  3. Теперь вам нужно преобразовать 12510 в X62 (база 62). 12510 = 2 × 621 + 1 × 620 = [2,1] Для этого требуется использование целочисленного деления и по модулю. Пример псевдокода:
    digits = []
    
    while num > 0
      remainder = modulo(num, 62)
      digits.push(remainder)
      num = divide(num, 62)
    
    digits = digits.reverse
    
    Теперь сопоставьте индексы 2 и 1 с вашим алфавитом. Так будет выглядеть ваше сопоставление (например, с массивом):
    0  → a
    1  → b
    ...
    25 → z
    ...
    52 → 0
    61 → 9
    
    С 2 → c и 1 → b вы получите cb62 как сокращенный URL.
    http://shor.ty/cb
    

Как разрешить сокращенный URL-адрес для начального ID

. Реверс еще проще. Вы просто выполняете обратный поиск в своем алфавите.

  1. e9a62 будет разрешен к «4-й, 61-й и 0-й букве в алфавите». e9a62 = [4,61,0] = 4 × 622 + 61 × 621 + 0 × 620 = 1915810
  2. Теперь найдите свою запись базы данных с помощью WHERE id = 19158 и выполните перенаправление.

Некоторые реализации (предоставленные комментаторами)

930
задан MSalters 1 June 2016 в 12:28
поделиться

5 ответов

936
ответ дан Alan 19 August 2018 в 04:45
поделиться
76
ответ дан Community 19 August 2018 в 04:45
поделиться
  • 1
    Хороший материал. Скоро придется перечитывать. +1 – sehe 10 July 2013 в 21:08
typedef typename Tail::inUnion<U> dummy;

Однако я не уверен, что реализация inUnion верна. Если я правильно понимаю, этот класс не должен быть создан, поэтому вкладка «fail» никогда не будет автоматически терпеть неудачу. Возможно, было бы лучше указать, находится ли тип в объединении или нет с простым булевым значением.

template <typename T, typename TypeList> struct Contains;

template <typename T, typename Head, typename Tail>
struct Contains<T, UnionNode<Head, Tail> >
{
    enum { result = Contains<T, Tail>::result };
};

template <typename T, typename Tail>
struct Contains<T, UnionNode<T, Tail> >
{
    enum { result = true };
};

template <typename T>
struct Contains<T, void>
{
    enum { result = false };
};

PS: Посмотрите на Boost :: Variant

PS2: посмотрите на typelists , особенно в книге Андрея Александреску: Modern C ++ Design

18
ответ дан Luc Touraille 19 August 2018 в 04:45
поделиться
  • 1
    inUnion & л; U & GT; был бы создан, если вы, например, попытались вызвать Union & lt; float, bool & gt; :: operator = (U) с U == int. Он вызывает частный набор (U, inUnion & lt; U & gt; * = 0). – MSalters 5 March 2009 в 11:52
  • 2
    И работа с result = true / false заключается в том, что мне понадобится boost :: enable_if & lt; & gt ;, что несовместимо с нашей текущей технологической привязкой OSX. Однако отдельный шаблон все же является хорошей идеей. – MSalters 5 March 2009 в 11:55
  • 3
    Люк означает typedef Tail :: inUnion & lt; U & gt; фиктивная; линия. который будет создавать экземпляр Tail. но не inUnion & lt; U & gt ;. он получает экземпляр, когда ему требуется полное его определение. это происходит, например, если вы берете sizeof или получаете доступ к члену (используя :: foo). @MSalters в любом случае, у вас есть еще одна проблема: – Johannes Schaub - litb 5 March 2009 в 15:56
  • 4
    -sizeof (U) никогда не является отрицательным :), потому что size_t представляет собой целочисленный тип без знака. вы получите очень большое количество. вы, вероятно, захотите сделать sizeof (U) & gt; = 1? -1: 1 или подобное :) – Johannes Schaub - litb 5 March 2009 в 15:58
  • 5
    я просто оставил бы его неопределенным и только объявил бы его: template & lt; typename U & gt; struct inUnion; поэтому он, конечно, не может быть создан. я думаю, что имея его с sizeof, компилятор также может дать вам ошибку, даже если вы not создаете экземпляр, потому что если знает sizeof (U) всегда & gt; = 1 и ... – Johannes Schaub - litb 5 March 2009 в 16:07

Я помещаю превосходный ответ JLBorges на аналогичный вопрос дословно из cplusplus.com, так как это наиболее краткое объяснение, которое я прочитал по этому вопросу.

] В шаблоне, который мы пишем, есть два типа имен, которые можно использовать - зависимые имена и не зависимые имена. Зависимое имя - это имя, которое зависит от параметра шаблона; неизменяемое имя имеет то же значение, независимо от параметров шаблона.

Например:

template< typename T > void foo( T& x, std::string str, int count )
{
    // these names are looked up during the second phase
    // when foo is instantiated and the type T is known
    x.size(); // dependant name (non-type)
    T::instance_count ; // dependant name (non-type)
    typename T::iterator i ; // dependant name (type)

    // during the first phase, 
    // T::instance_count is treated as a non-type (this is the default)
    // the typename keyword specifies that T::iterator is to be treated as a type.

    // these names are looked up during the first phase
    std::string::size_type s ; // non-dependant name (type)
    std::string::npos ; // non-dependant name (non-type)
    str.empty() ; // non-dependant name (non-type)
    count ; // non-dependant name (non-type)
}

То, что зависит от зависимого имени, может быть чем-то другим для каждого конкретного экземпляра шаблона. Как следствие, шаблоны C ++ подвержены «двухфазному поиску имен». Когда шаблон сначала анализируется (до того, как выполняется какое-либо создание), компилятор просматривает не зависящие имена. Когда происходит конкретное создание шаблона, параметры шаблона известны к тому времени, и компилятор ищет зависимые имена.

На первом этапе анализатор должен знать, является ли зависимое имя именем типа или имени не-типа. По умолчанию зависимым именем считается имя не-типа.

Использовать ключевое слово typename только в объявлениях шаблонов и определениях, приведенных ниже.


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

0
ответ дан Nik-Lz 19 August 2018 в 04:45
поделиться
125
ответ дан Community 30 October 2018 в 16:38
поделиться
Другие вопросы по тегам:

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