typedef vs using - отличия компилятора [duplicate]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

670
задан Varaquilex 7 May 2014 в 14:16
поделиться

4 ответа

Они эквивалентны из стандартного (основное внимание) (7.1.3.2):

Имя typedef также может быть введено с помощью объявления alias. Идентификатор, следующий за ключевым словом using, становится typedef-name и необязательным атрибутом-спецификатором-seq, следующим за идентификатором, к этому typedef-name. Он имеет ту же семантику, как если бы он был введен спецификатором typedef. В частности, он не определяет новый тип и не должен отображаться в идентификаторе типа.

443
ответ дан Jesse Good 18 August 2018 в 19:05
поделиться
  • 1
    Из ответа ключевое слово using представляется надмножеством typedef. Тогда будет ли typdef устаревать в будущем? – iammilind 25 May 2012 в 05:28
  • 2
    @iammilind, вероятно, нет, но вы можете закодировать, как если бы это было так. – bames53 25 May 2012 в 06:09
  • 3
    Отклонение не обязательно указывает на намерение удалить - оно просто выступает как очень сильная рекомендация предпочесть другие средства. – Iron Savior 20 April 2013 в 21:37
  • 4
    Но потом я удивляюсь, почему они не просто разрешили шаблон typedef. Я помню, что где-то читал, что они ввели синтаксис using именно потому, что семантика typedef плохо работала с шаблонами. Что-то противоречит тому факту, что using определяется как одна и та же семантика. – celtschk 21 July 2013 в 10:44
  • 5
    @celtschk: о чем говорится в предложении n1489. Алиас шаблона not - псевдоним для типа, но псевдоним для группы шаблонов. Чтобы провести различие между typedef, почувствовал необходимость в новом синтаксисе. Кроме того, имейте в виду, что вопрос OP о разнице между версиями без шаблонов. – Jesse Good 21 July 2013 в 23:19

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

template <typename T> struct whatever {};

template <typename T> struct rebind
{
  typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};

rebind<int>::type variable;

template <typename U> struct bar { typename rebind<U>::type _var_member; }

Но использование синтаксиса упрощает этот прецедент.

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
155
ответ дан 4xy 18 August 2018 в 19:05
поделиться
  • 1
    Я уже указал это на вопрос. Мой вопрос о том, если вы не используете шаблон, есть ли разница с typedef. Например, когда вы используете 'Foo foo {init_value};' вместо «Foo foo (init_value)» оба должны делать одно и то же, но не использовать точно такие же правила. Так что мне было интересно, есть ли схожая скрытая разница с использованием / typedef. – Klaim 2 May 2014 в 20:57

Они по существу одинаковы, но using обеспечивает alias templates, что весьма полезно. Один хороший пример, который я мог найти, следующий:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

Итак, мы можем использовать std::add_const_t<T> вместо typename std::add_const<T>::type

8
ответ дан Validus Oculus 18 August 2018 в 19:05
поделиться

Они в основном одинаковы, за исключением того, что

The alias declaration is compatible with templates, whereas the C style typedef is not.

129
ответ дан Zhongming Qu 18 August 2018 в 19:05
поделиться
  • 1
    Особенно любят простоту ответа и указывают на происхождение набора. – g24l 12 November 2015 в 14:34
Другие вопросы по тегам:

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