Вы можете использовать ключевое слово 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
ошибки при вызове с явными литералами массива char, как в следующем случае
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?
person
Nordlöw
schedule
15.06.2011
private
. - person John Dibling   schedule 09.03.2010struct
вместоclass
для педагогической простоты? Я нахожу код, который компилируется, легче учиться ;-) - person Steve Jessop   schedule 09.03.2010