Использование boost::mpl::vector для создания шаблонов с переменными параметрами?
Я сейчас застрял с C++03 и хочу создать глобальную функцию, которая принимает любое количество аргументов, безопасных для типов (вплоть до разумного предела, если необходимо, например, 9).
У меня есть доступ к полной библиотеке надстроек в моей базе кода, так что я надеюсь boost::mpl::vector
может быть полезно здесь. Я также не хочу, чтобы это было слишком неудобно, чтобы писать. Синтаксис на сайте вызова должен быть простым, например:
LogDebugMessage("Number of cats and dogs:", m_myPets->NumCats(), m_myPets->NumDogs());
Каков наилучший способ реализовать это безопасным способом?
РЕДАКТИРОВАТЬ
Я также понимаю, что могу использовать специализацию шаблонов для этого, но я не хочу в конечном итоге определять одну и ту же структуру 9 раз, по одному для каждого дополнительного параметра шаблона. Это слишком грязно для этого. Я хотел бы избежать этого, если это вообще возможно.
1 ответ
Лучше всего было бы 9 перегрузок.:П
Однако самый простой способ для вас - boost::tuple
Вместо того, чтобы использовать boost::mpl
, поскольку mpl
в основном только во время компиляции. Сайт вызова (пользователь) будет писать что-то вроде
LogDebugMessage("Number of cats and dogs:",
boost::tie(m_myPets->NumCats(), m_myPets->NumDogs()));
tie
создает кортеж ссылок. Или, если вызов включает временные:
LogDebugMessage("Number of cats, dogs and birds:",
boost::make_tuple(m_myPets->NumCats(), m_myPets->NumDogs(), 0));
Если зарегистрированные типы немного тяжелее (boost::make_tuple
делает копии), можно прибегнуть к старому доброму boost::ref
,
Ваш LogDebugMessage
будет выглядеть примерно так:
template<class Tuple>
void LogDebugMessage(std::string const& msg, Tuple const& args);
И после этого вы распакуете кортеж, используя рекурсию, похожую на мой принтер кортежей. Обратите внимание, что только operator<<
на самом деле использует шаблоны Variadic, и только делает это, чтобы просто подобрать std::tuple
, Скорее всего, вы будете использовать только print_tuple
часть.