Это совершенно правильный код, и gcc прав. «Особенность» была введена в C ++ 17 . Это не особенность, потому что это отчет о дефектах. MyDelegate
соответствует частичной специализации signature_traits
, и поэтому его следует воспринимать как gcc правильно. Обратите внимание, что он работает, потому что второй параметр шаблона по умолчанию установлен.
Причина, по которой clang не компилирует ее, состоит в том, что этот дефектный отчет имеет дефект: P. Он не вводит соответствующие изменения в частичном упорядочении , что не очень приятно и делает ранее допустимый код неоднозначным.
Ожидается, что он будет исправлен в ближайшее время, но в Тем временем, clang решил «скрыть» функцию за флагом -frelaxed-template-template-args.
Итак, просто скомпилируйте этот флажок, и все будет в порядке.
вам нужно сделать
class one{
Integer b;
{
b=Integer.valueOf(2);
}
}
, поскольку операторы должны появиться в блоке кода.
В этом случае блок является блоком инициализатора, который добавляется к каждому конструктор (или конструктор по умолчанию в этом случае) Он запускается после любого вызова super()
и перед основным блоком кода в любом конструкторе.
BTW: у вас может быть статический блок инициализации с static { }
, который вызывается, когда класс инициализирован.
например
class one{
static final Integer b;
static {
b=Integer.valueOf(2);
}
}
Я думаю, что терминология, пара других ответов немного отброшены. Объявления также являются заявлениями. Фактически, они называются «заявлениями заявления», которые являются одним из трех видов утверждений. Оператор присваивания является одной из форм выражения «выражение» и может использоваться только в конструкциях, таких как методы, конструкторы и инициализаторы. Просмотрите раздел «Заявления» в этой ссылке учебника Oracle .
В Java при определении класса вы можете определить переменные со значениями по умолчанию и добавить методы. Любой исполняемый код (например, присвоения) ДОЛЖЕН содержаться в методе.
Более общий ответ заключался бы в том, что тело класса относится к объявлениям, а не к утверждениям. Существует специальное условие для выражений, происходящих в классе, но они должны быть помечены явно как инициализаторы классов или инициализаторы экземпляров.
Поскольку присваивания являются операторами и утверждениями разрешены только внутри блоков кода (методы, конструкторы, статические инициализаторы и т. д.)
За пределами этих разрешений разрешены только.
Это:
class one{
Integer b=Integer.valueOf(2);
}
- это объявление с инициализатором. Вот почему принято
Так работает java, вы не можете добавить код не декларации (извините, что я не знаю правильный термин) внутри класса, этот код должен быть внутри методов.
Методы несут ответственность за выполнение мутаций в переменных-членах. Если переменная-член должна быть инициализирована, java предоставляет способ сделать это во время построения, определение класса (последний случай). Но мутация не может быть выполнена во время определения (прежний случай). Обычно это делается на уровне метода.
Объекты предназначены для хранения состояния, а методы предназначены для работы в этом состоянии.