LINUX.ORG.RU

Шаблоны в С++


0

0

Почему следующий пример неправомерен?

 void f()
{
        class functor
        {
                public:
                void operator()(int i) {std::cout << i << std::endl;}
        };

        functor func;
        std::vector<int> vec(10);
        std::for_each(vec.begin(), vec.end(), func);
}

это faq. локальные классы в современном стандарте имеют no linkage — отсюда их нельзя использовать как аргумент шаблона.

(foreach — шаблонная функция и аргумент шаблона выводится из типа func)

dilmah ★★★★★
()

можно вот так (под begin-end сам перепишешь)

заодно шаблон подокументированнее твоего

из недостатков — виртуальный вызов

#include <iostream>
#include <vector>

int main();

struct AbstractFunctor
{
    virtual void operator()(int) const = 0;
};
template<class E> void for_each(std::vector<E>& v, const AbstractFunctor& functor)
{
    for(unsigned int i=0; i<v.size(); i++) functor(v[i]);
}

int main()
{
    struct Functor: public AbstractFunctor
    {
        void operator()(int i) const {std::cout << i << std::endl;}
    };

    const AbstractFunctor& functor = *(new Functor());
    std::vector<int> vec(10);
    for_each(vec, functor);
    return 0;
}
www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Begemoth

OS освободит :-) у меня другие мысли крутились, поэтому я не написал просто

const AbstractFunctor& functor = Functor();

там еще интересная грабля есть:

#include <iostream>

struct Printer
{
    Printer() { std::cout << "ctr at " << int(this) << std::endl; }
    ~Printer() { std::cout << "dtr at " << int(this) << std::endl; }
};

Printer p() { return Printer(); }

void f()
{
    const Printer& r1 = *(new Printer());
    const Printer& r2 = p();
    const Printer& r3 = Printer();
    std::cout << "r1  at " << int(&r1) << std::endl;
    std::cout << "r2  at " << int(&r2) << std::endl;
    std::cout << "r3  at " << int(&r3) << std::endl;
}

int main()
{
    std::cout << "start" << std::endl;
    f();
    std::cout << "end" << std::endl;
    return 0;
}

выхлоп:

start
ctr at 134520840
ctr at -1073744318
ctr at -1073744317
r1  at 134520840
r2  at -1073744318
r3  at -1073744317
dtr at -1073744317
dtr at -1073744318
end

нет деструктора r1

недавно вроде обсуждали что-то похожее

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

нет деструктора r1

недавно вроде обсуждали что-то похожее

А с какой радости он должен вызываться? Объект-то ты явно не уничтожаешь, а при завершении программы вызываются деструкторы только статически выделенных объектов.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

должен, так как объект держит константная ссылка ( посмотри, например, когда вызывается деструктор временного объекта, созданного аж в функции р() )

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Begemoth

немного подумав, понял, что объект, явно создаваемый с помощью new ну никак нельзя назвать временным, так что деструктор у него вызываться конечно не должен

www_linux_org_ru ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.