Вы можете использовать ключевое слово C ++ 0x auto
вместе с специализацией шаблона , например, для функции с именем boost::make_array()
(аналогично make_pair()
). Для случая, когда N
равен 1 или 2 аргументам, мы можем написать вариант A как
namespace boost
{
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
return boost::array<T,2> ({{ a }});
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
return boost::array<T,2> ({{ a, b }});
}
}
и вариант B как
namespace boost {
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
boost::array<T,1> x;
x[0] = a;
return x;
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
boost::array<T,2> x;
x[0] = a;
x[1] = b;
return x;
}
}
GCC-4.6 с -std=gnu++0x
и -O3
генерирует точно такой же двоичный код для
auto x = boost::make_array(1,2);
с использованием A и B , как для
boost::array<int, 2> x = {{1,2}};
Для пользовательских типов (UDT), однако, вариант B приводит к дополнительному конструктору копирования , который обычно замедляет работу, и поэтому его следует избегать.
Обратите внимание, что boost::make_array
выдает ошибки при вызове его с явными литералами массива символов, как в следующем случае
auto x = boost::make_array("a","b");
Я считаю, что это хорошо, поскольку const char*
литералы могут быть обманчивыми в их использовании.
Шаблоны Variadic , доступные в GCC начиная с 4.5, могут в дальнейшем использоваться для сокращения всего кода шаблона специализации шаблонов для каждого N
до определения одного шаблона из boost::make_array()
определяется как
/*! Construct Array from @p a, @p b. */
template <typename T, typename ... R>
boost::array<T,1+sizeof...(R)> make_array(T a, const R & ... b)
{
return boost::array<T,1+sizeof...(R)>({{ a, b... }});
}
Это работает почти так, как мы ожидаем. Первый аргумент определяет boost::array
шаблонный аргумент T
, а все остальные аргументы преобразуются в T
. В некоторых случаях это может быть нежелательно, но я не уверен, как, если это возможно, указать с помощью шаблонов с переменными значениями.
Может быть, boost::make_array()
должен войти в Boost Libraries?