All streams
Search
Write a publication
Pull to refresh
39
0
Виктор Щерба @vScherba

Разработчик C++

Send message
Я и не утверждал, что это в стандарте написано. Я хочу сказать, что дебаг режим не обязан поддерживать стандарт в требованиях эффективности. Главное, чтобы семантику не портил. Ведь польза этого режима как раз во всевозможных «тормозных» проверках. Иначе этот режим потеряет смысл, следуя требованиям эффективности
А 2 указателя пробовали сложить?
На дебаг режим это не распространяется. Много чего в дебаге не соответствует требованиям сложности.
Вполне логично. В дебаге чем больше проверок, тем лучше. Мы когда перевели свой проект с VS2003 на VS2008 несколько интересных багов обнаружили.
1. Самой логичной реализацией итераторов для std::vector является обычный указатель (завернутый в обертку или даже без нее). Отсюда такое поведение в релизе.
2. В отладочном режиме MS VC2008 и выше (скорее всего и в других компиляторах также) Вы получите кучу debug-assert'ов на своем примере. В debug как раз есть проверки на принадлежность итераторов конкретному контейнеру и многие другие проверки. Но в release такие проверки — это лишний оверхед.
3. Смысл сложения 2-х итераторов? Что в результате? Вычитание же не обделено смыслом.
На C++03 можно переделать так:

template <typename T>
class VectorWrapper
{
public:

    template <typename C>
    VectorWrapper(C& container) :
    _getter(boost::bind(&C::operator[], &container, _1)),
    _sizeGetter(boost::bind(&C::size, &container))
    {
    }

    T& operator[](size_t i)
    {
        return _getter(i);
    }

    size_t size()
    {
        return _sizeGetter();
    }

private:
    boost::function<T&(size_t) > _getter;
    boost::function<size_t() > _sizeGetter;
};
Насчет оптимизации передачи аргумента const X&:
Если функция встраивается (inline), то никакого получения адреса / разыменования внутри функции не будет. Если встраивается ее вызов, тогда да, будет.
Для написания переносимого кода можно воспользоваться boost::param_type<X>::type. Буст поможет решить, как передавать параметр: по константной ссылке или по значению.
Порядок, да, может быть любым. Но, если рассматривать одну конкретную переменную, то dimoclus прав: сразу после выполнения mov [mem],value в [mem] увидим значение value с любого ядра. Это гарантирует когерентность кэша. Протоколы разные, но почти все архитектуры их имеют (за исключением парочки экзотических). Перед тем как прочитать [mem] гарантируется, что протокол поддержки когерентности отработал.
Вот хорошая ссылка по Memory Barriers.
Ваши функции, к сожалению, не могут возвращать значения. Вернее они возвращают значение типа класса, который они конструируют. В BOOST_LOCAL_FUNCTION уже есть решение вложенных функций.
Попробуйте оба варианта в релизе с максимальной настройкой оптимизации компилятора, сделайте замеры производительности на хорошо нагруженном примере и сравните. Если [=] окажется не менее производительным, чем [&], выбрасывайте список, код упростится.
Мне кажется, если поверхностно смотреть, то не нужен list вообще, если вставить shared_ptr на место
realfunc *f; //указатель на элемент коллекции
в class func_t.

Может, я чего-то не учел.
shared_ptr<realfunc> f;
Угловые скобки съелись.
А статический список, если я правильно понял, используется только для вечного хранения realfunc объектов, он всегда растет при конструировании func_t и очищается только по завершении программы? Я бы посмотрел в сторону shared_ptr и хранил бы его вместо realfunc *f, если нет циклических ссылок. Список был бы не нужен.
ЗдОрово. А еще можно переписать без лямбд, тогда код будет работать на компиляторах без поддержки C++11. Вот на примере оператора сложения:

func_t operator+ (const func_t &arg, const func_t &arg2)
{
    struct _sum
    {
        _sum(const func_t &arg, const func_t &arg2)
            : _arg(arg), _arg2(arg2){}

        double operator()(double x)
        {
            return (*_arg.f)(x) + (*_arg2.f)(x);
        }

        const func_t& _arg;
        const func_t& _arg2;
    };

    realfunc realf = _sum(arg, arg2);
    return func_t(realf);
}

Хотя, коряво все это выглядит без лямбд.
Все верно. Я вот тут посидел, повспоминал, вроде никогда не использовал list. В основном vector. В случае больших массивов, в которые в конец идут частые вставки — deque. Полагаю, что list следует использовать в специфических задачах не для получения производительности, а когда по каким-то причинам нам очень не хочется, чтобы элементы перемещались в памяти и не портились указатели и итераторы на них. Скорее всего, он будет полезен для построения графов, где часто добавляются и удаляются вершины с ребрами, которые ссылаются друг на друга через указатели. По-моему, в Boost Graph Library в самая популярное представление графа строится на std::list (класс adjacency_list).
Дык то ж семантика, а не предлагаемая реализация. То есть, описывается эквивалент, который будет давать тот же семантический результат, что и size(). То есть, стандарт требует, чтобы distance(a.begin(),
a.end()) == a.size().
Это временно. В новом стандарте § 23.2.1 требования к сложности size() всех STL-контейнеров = const.
Мне нравится как перегрузка с наследованием решена в C++. В перегрузке участвуют только методы того типа, у которого мы их вызываем, имена методов базового класса скрываются (hide) независимо от виртуальности. Если разработчик хочет, чтобы имя в производном классе было перегружено совместно с именем из базового класса, он это указывает явно, внесением имени в область видимости производного класса: using base::foo; (unhide). Вот и все, четко и понятно, никаких неожиданностей. Тема перегрузки и тема замещения виртуальной функции в C++ не пересекаются. Могли бы для шарпа что-то подобное придумать.

Пример:
struct base
{
    void foo(int);
};

struct derived : base
{
    // using base::foo; // раскомментить для перегрузки с foo(int)
    void foo(double);
};
В данном примере LoadLibrary(«ntdll.dll») не вызовет течь. Под NT ntdll.dll и так всегда загружена в процесс. Лишь инкрементирует счетчик загруженной библиотеки. Разве что не эстетично это. Так лучше было бы: GetModuleHandle(«ntdll.dll»).

Information

Rating
Does not participate
Location
Дубна, Москва и Московская обл., Россия
Date of birth
Registered
Activity