Если вы хотите установить точность для всех decimals
в EF6, вы можете заменить стандартное соглашение DecimalPropertyConvention
, используемое в DbModelBuilder
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<DecimalPropertyConvention>();
modelBuilder.Conventions.Add(new DecimalPropertyConvention(38, 18));
}
По умолчанию DecimalPropertyConvention
в EF6 отображает свойства decimal
в столбцы decimal(18,2)
.
Если вы хотите, чтобы отдельные свойства имели заданную точность, вы можете установить точность для свойства объекта в DbModelBuilder
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().Property(e => e.Value).HasPrecision(38, 18);
}
Или добавьте EntityTypeConfiguration<>
для объекта, который задает точность:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MyEntityConfiguration());
}
internal class MyEntityConfiguration : EntityTypeConfiguration<MyEntity>
{
internal MyEntityConfiguration()
{
this.Property(e => e.Value).HasPrecision(38, 18);
}
}
По-видимому, решение - то, какая основа () возвраты 1 прочь. Следующие идентификационные данные содержат для reverse_iterator:
&*(reverse_iterator(i)) == &*(i - 1)
Или другими словами, reverse_iterator всегда является одной передачей регулярный итератор, из которого это является основа. Не уверенный, почему.
Просто изменяются
// SEGFAULT HERE
setOfInts.erase( rev_iter.base());
к [1 110]
// WORKS!
setOfInts.erase( --rev_iter.base());
, мне определенно любопытно, хотя относительно того, почему идентификационные данные выше имеют смысл.
, Возвращающемся в работу и пробующем это в Visual Studio, я вижу, что вышеупомянутое решение не вполне работает. "nextIter" становится недопустимым на стирании. Вместо этого необходимо сохранить далеко временный файл от стирания для получения следующего итератора вместо того, чтобы иметь в наличии nextIter как вышеупомянутый.
set<int>::iterator tempIter = setOfInts.erase(--rev_iter.base());
rev_iter = setOfInts.erase(tempIter);
, Таким образом, конечное решение
int main()
{
using namespace std;
set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
set<int>::reverse_iterator rev_iter = setOfInts.rbegin();
while ( rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
{
cout << "Erasing : " << *rev_iter;
set<int>::iterator tempIter = setOfInts.erase( --rev_iter.base());
rev_iter = set<int>::reverse_iterator(tempIter);
}
else
{
++rev_iter;
}
}
}
Примечание, ассоциативные контейнеры не возвращают итератор из стирания. Таким образом, это решение не работало бы на карту, мультикарту, и т.д.
Звоните erase
с самим итератором (никакая потребность использовать base
).
#include <set>
#include <iostream>
int main()
{
std::set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
std::set<int>::reverse_iterator rev_iter = setOfInts.rbegin();
while (rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
{
rev_iter = setOfInts.erase(rev_iter);
}
else
{
++rev_iter;
}
}
}
кроме того, Вам не нужен тот отдельный "следующий" итератор (см. выше изменений). Еще лучший способ сделать это должно использовать std::remove_if
(или функция как он).
Когда вы выполняете итерацию с обратным итератором и хотите использовать base () для изменения его контейнера, всегда сохраняйте в виду, что reverse_iterator всегда основан на следующем итераторе из исходного порядка. Это немного неинтуитивно, но на самом деле упрощает код:
#include <set>
int main()
{
std::set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
typedef std::set<int>::reverse_iterator RevIter;
RevIter rev_iter = setOfInts.rbegin();
while (rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
setOfInts.erase(--rev_iter.base());
++rev_iter;
}
}
В этом примере нет необходимости сохранять «следующий» итератор, поскольку базовый итератор не аннулируется! (Нам это действительно нужно при работе с обычными итераторами.)
Поведение обратных итераторов создает странные постепенные трудности при работе с одним элементом, но на самом деле оно упрощает диапазоны:
riValue = find(riEnd.base(), riBegin.base(), value);
использует в точности те же объекты (в обратном порядке), что и
iValue = find(riBegin, riEnd, value);