(5 comments) - (Post a new comment)
(Reply to this) (Thread)
//------------------------------------------------ //Classes.h #include <vector> using namespace std; struct A { A(); int x; }; class C { public: C(); void check() const; private: struct B { B(); double x; double y; }; private: vector<A> av; vector<B> bv; }; //-------------------------------------------------- // classes.cpp #include "Classes.h" #include "Filler.h" #include <assert.h> A::A(): x (5) { } C::C() { Filler::fill<vector<A>, A>(5, av); Filler::fill<vector<B>, B>(5, bv); } C::B::B(): x(0), y(0) { } void C::check() const { assert(av[0].x == 5); assert(bv[0].x == 0); } //--------------------------------------------------- //Filler.h #include <vector> using namespace std; struct Filler { template <class T> struct ItemCreater { virtual T createItem() { return T(); } }; template <class TSTLContainer, typename T> static void fill(int size, TSTLContainer & container, ItemCreater<T> & creater = ItemCreater<T>()); }; template <class TSTLContainer, typename T> static void Filler::fill(int size, TSTLContainer & container, ItemCreater<T> & creater) { for(int i = 0; i != size; ++i) { container.insert(container.end(), creater.createItem()); } } //--------------------------------------- // main.cpp #include "Filler.h" #include "Classes.h" void main() { C c; c.check(); } </code></pre>
(Reply to this) (Parent)
Если кратко — студия компилирует некорректный код, не выдавая при этом ошибок.
В примере, есть как минимум одна ошибка. При out-of-class определении шаблонной статической функции члене класса нельзя указывать static. В объявлении нужно, в определении нельзя.
Вторая погрешность не запрещена стандартом (на сколько я знаю), но потенциально может привести к неприятностям. Кстати, g++ считает ее ошибкой. Проблема в коде ItemCreater<T> & creater = ItemCreater<T>(). Неконстантная ссылка принимает временный объект. Нет нужды говорить об опасности такого подхода в общем случае.
ItemCreater<T> & creater = ItemCreater<T>()
Простейшая модификация кода, позволяющая корректно откомпилировать его студией — замена ItemCreater & creater = ItemCreater() на ItemCreater creater = ItemCreater().
ItemCreater & creater = ItemCreater()
ItemCreater creater = ItemCreater()
Следующий вариант модификации:
struct Filler { template <class TSTLContainer, typename T> static void fill(int size, TSTLContainer & container) { for (int i = 0; i != size; ++i) { container.insert(container.end(), T()); } } template <class TSTLContainer, typename T, typename F> static void fill (int size, TSTLContainer & container, F creater) { for(int i = 0; i != size; ++i) { container.insert(container.end(), creater()); } } };
int foo() { return 1; } struct bar { double operator()() { return 1.0; } }; void func() { vector<char> av; Filler::fill<vector<char>, char>(5, av); vector<int> bv; Filler::fill<vector<int>, int>(5, bv, foo); vector<double> cv; Filler::fill<vector<double>, double>(5, cv, bar()); }