Считаете ли вы, что вы создаете свой собственный шаблон EditorTemplate для лица, отправителя и получателя? EditorFor и DisplayFor ищут настраиваемый шаблон, соответствующий типу объекта.
Внутренний метод будет искать шаблон, соответствующий типу объекта. Затем он будет искать шаблон, соответствующий базовому классу, а затем по цепочке наследования.
работает нормально и производит ожидаемый результат вместо любой ошибки времени выполнения.
Это основная ошибка допущения.
Приложение: обратите внимание, что при наличии дефекта CWG ( # 315
Addendum: g0]), который закрывается как «согласованный» , а не , делающий вышеуказанный UB, он полагается на положительное закрытие другого дефекта CWG (
# 232 ), который по-прежнему активен, и, следовательно, ни один из них не добавлен к стандарту.Позвольте мне привести часть комментария из Джеймса Макнеллиса к an ответьте на аналогичный вопрос переполнения стека:
Я не думаю, что дефект CWG 315 «закрыт», поскольку его присутствие на странице «закрытые проблемы» подразумевает. В обосновании говорится, что это должно быть разрешено, потому что «* p не является ошибкой, когда p равно null, если значение lvalue не преобразуется в значение r». Тем не менее, это зависит от концепции «пустой lvalue», которая является частью предлагаемой резолюции для дефекта CWG 232, но которая не была принята.
То, что вы видите здесь, - это то, что я считаю неправильным и неудачным выбором дизайна в спецификации языка C ++ и многих других языков, принадлежащих к одному и тому же общему семейству языков программирования.
Эти языки позволяют ссылаться на статические члены класса, используя ссылку на экземпляр класса. Фактическое значение ссылки на экземпляр, конечно, игнорируется, поскольку для доступа к статическим членам не требуется экземпляр.
Итак, в d->fun();
компилятор использует указатель d
только во время компиляции , чтобы понять, что вы обращаетесь к члену класса demo
, а затем игнорируете его. Никакой код не испускается компилятором для разыменования указателя, поэтому факт, что он будет NULL во время выполнения, не имеет значения.
Итак, то, что вы видите, происходит в полном соответствии со спецификацией язык, и, на мой взгляд, спецификация страдает в этом отношении, потому что это позволяет сделать нелогичную вещь: использовать ссылку на экземпляр для ссылки на статический член.
PS Большинство компиляторов на большинстве языков на самом деле способны выдавать предупреждения для такого рода материалов. Я не знаю о вашем компиляторе, но вы можете проверить, потому что тот факт, что вы не получили предупреждения о том, что вы делали, может означать, что у вас недостаточно предупреждений.
template <class T> f(T &t) { t.g(); } struct StillWorking { void g() {} }; struct NowBroken { static void g(); } }; f(StillWorking()); f(NowBroken());
– Christian Hackl
12 February 2015 в 18:02
const&
(моя не будет компилироваться в любом случае), но точка стоит.
– Christian Hackl
12 February 2015 в 18:05
Из C ++ Draft Standard N3337:
9.4 Статические элементы
2 Элементы
blockquote>static
классаX
классаX
могут ссылаться на использование expression-id expressionX::s
; нет необходимости использовать синтаксис доступа к члену класса (5.2.5) для ссылки на членstatic
. Членstatic
может ссылаться на использование синтаксиса доступа к члену класса, и в этом случае оценивается выражение объекта.И в разделе об объектном выражении ...
5.2.5 Доступ к члену класса
4 Если объявлено, что E2 имеет тип «ссылка на T», тогда E1.E2 является lvalue; тип E1.E2 - T. В противном случае применяется одно из следующих правил.
- Если
blockquote>E2
является членом данныхstatic
, а типE2
-T
, тоE1.E2
- значение l; выражение обозначает именованный член класса. ТипE1.E2
- T.На основании последнего параграфа стандарта выражения:
d->fun(); std::cout << d->a;
работают, потому что оба они обозначают именованный элемент класса независимо от значения
d
.
d
не указывать на какой-либо объект?
– Deduplicator
12 February 2015 в 18:13
E1
в этой цитате, извините.
– Deduplicator
12 February 2015 в 18:20
.
необходимо оценить, даже если он статичен, или g().f()
может не оценить g()
.
– T.C.
12 February 2015 в 18:42