boost::mpl::_1
и boost::mpl::_2
являются заполнителями; они могут использоваться в качестве параметров шаблона, чтобы отличать привязку к фактическому аргументу для более позднего времени. При этом вы можете выполнять частичное применение (преобразование мета-функции, имеющей n-арность, в функцию, имеющую (nm) -арность), лямбда-выражения (создание мета-функции на лету там, где это необходимо) и т. Д.
Выражение, содержащее хотя бы заполнитель, является выражением-заполнителем, которое можно вызывать, как и любую другую метафункцию, с некоторыми аргументами, которые заменят заполнители.
В вашем примере, предполагая следующее typedef
typedef boost::flyweights::hashed_factory_class<
boost::mpl::_1,
boost::mpl::_2,
boost::hash<boost::mpl::_2>,
std::equal_to<boost::mpl::_2>,
std::allocator<boost::mpl::_1>
> hashed_factory;
мы можем предположить, что в какой-то другой точке кода hashed_factory
будет вызываться с некоторым параметром:
typedef typename
boost::mpl::apply<
hashed_factory,
X,
Y
>::type result; // invoke hashed_factory with X and Y
// _1 is "replaced" by X, _2 by Y
Я не смотрел код Flyweight, но можно предположить, что _1
будет привязан к типу значения flyweight, а _2
- к типу ключа (так как он используется для хеширования и проверки равенства). В этом случае я думаю, что оба будут std::string
, так как тип ключа не указан.
Я не уверен, что мое объяснение о заполнителях MPL достаточно ясное, не стесняйтесь читать превосходный учебник MPL , который очень хорошо объясняет метафункции, лямбда-выражения и другие функции метапрограммирования шаблонов.