Вам нужно будет использовать кисть внутри кисти, а внешняя кисть должна быть сеткой из прямоугольников 2x2 или чем-то вроде того, чтобы получить этот рисунок шахматной доски. Это должно сделать работу:
Результат:
Более быстрый метод, если вы можете уйти с его помощью - визуализировать линии шахматной доски и сетки в виде отдельных слоев. Это позволяет вам рендерить все с геометриями, а не с формами:
Ответ на это является зависимым компилятора. Некоторые версии компилятора C++ Sun обработали бы это автоматически путем создания кэша из шаблонных реализаций функции, которые будут совместно использованы через отдельные единицы перевода.
При использовании Visual C++ и какого-либо другого компилятора, который не может сделать этого, можно также поместить функциональное определение в заголовок.
Не волнуйтесь о дублирующихся определениях, если заголовок включен несколькими .cc файлами. Компилятор отмечает сгенерированные шаблоном методы со специальным атрибутом, таким образом, компоновщик знает для выбрасывания дубликатов вместо жалобы. Это - одна причина, почему C++ имеет "одно правило определения".
Править: Вышеупомянутые комментарии применяются в общем случае, где Ваш шаблон должен быть способен к соединению, учитывая любые параметры типа. Если Вы знаете замкнутое множество типов, которые будут использовать клиенты, можно удостовериться, что они доступны при помощи явного инстанцирования в файле реализации шаблона, который заставит компилятор генерировать определения для других файлов для соединения против. Но в общем случае, где Ваш шаблон должен работать с типами, возможно только известными клиенту, затем существует мало точки в разделении шаблона в заголовочный файл и и файл реализации; любой клиент должен включать обе части так или иначе. Если Вы хотите изолировать клиенты от сложных зависимостей, скрыть те зависимости позади нешаблонных функций и затем звонить в них из кода шаблона.
Разделение его в файлы Как Вы хочет:
Не то, чтобы я рекомендую это. Просто показ, что это возможно.
plop.h
#include <iostream>
class Foo
{
public:
Foo(): member_(15){}
// Note No definition of this in a header file.
// It is defined in plop.cpp and a single instantiation forced
// Without actually using it.
template <typename F>
void func(F f);
private:
int member_;
};
struct Bar
{
void bar_func(int val) { std::cout << val << "\n"; }
};
struct Tar
{
void tar_func(int val) { std::cout << "This should not print because of specialisation of func\n";}
};
Plop.cpp
#include "plop.h"
#include <boost/bind.hpp>
#include <iostream>
template <typename F>
void Foo::func(F f)
{
f(member_);
}
// Gnarly typedef
typedef boost::_bi::bind_t<void, boost::_mfi::mf1<void, Bar, int>, boost::_bi::list2<boost::_bi::value<Bar>, boost::arg<1> (*)()> > myFunc;
// Force the compiler to generate an instantiation of Foo::func()
template void Foo::func<myFunc>(myFunc f);
// Note this is not a specialization as that requires the <> after template.
// See main.cpp for an example of specialization.
main.cpp
#include "plop.h"
#include <boost/bind.hpp>
#include <iostream>
// Gnarly typedef
typedef boost::_bi::bind_t<void, boost::_mfi::mf1<void, Tar, int>, boost::_bi::list2<boost::_bi::value<Tar>, boost::arg<1> (*)()> > myTar;
// Specialization of Foo::func()
template<> void Foo::func<myTar>(myTar f)
{
std::cout << "Special\n";
}
// Note. This is not instantiated unless it is used.
// But because it is used in main() we get a version.
int main(int argc,char* argv[])
{
Foo f;
Bar b;
Tar t;
f.func(boost::bind(&Bar::bar_func, b, _1)); // Uses instantiation from plop.cpp
f.func(boost::bind(&Tar::tar_func, t, _1)); // Uses local specialization
}
Вы включаете foo.cc в caller.cc. Инстанцирование - что-то, что происходит во время компиляции - когда компилятор видит вызов в вызывающей стороне, это делает инстанцированные версии шаблонов, но должно иметь полное определение в наличии.
Я думаю, к чему они оба обращаются, то, что шаблонные определения функции (не только объявления) должны быть включены в файл, где они используются. Шаблонные функции на самом деле не существуют, если/до они не используются; если Вы вставляете их отдельный cc файл, то компилятор не знает о них в других cc файлах, если Вы явно #include
это cc файл или в заголовочный файл или в файл, который это называет ими, из-за пути синтаксический анализатор, работает.
(Вот почему шаблон функциональные определения обычно сохраняется в заголовочных файлах как описанный Earwicker.)
Немного более ясный?
Я полагаю, что Earwicker корректен. Проблема с явным инстанцированием шаблонной функции членства func в этом случае состоит в том что тип, возвращенный повышением:: свяжите является зависящим от реализации. Это не повышение:: функция. Повышение:: функция может содержать boost:bind, потому что она имеет шаблонный оператор присваивания, который выводит тип правой стороны (повышение:: свяжите результат). В этом конкретном использовании func в caller.cc, с этой конкретной реализацией повышения, типом повышения:: свяжите на самом деле, они вводят упомянутый по ошибке компоновщика между <и> (т.е. boost::_bi::bind_t...
). Но явно инстанцирование func для того типа, вероятно, будет иметь проблемы мобильности.