您可以将C++0x auto
关键字与模板特化一起用于例如名为boost::make_array()
(类似于make_pair()
)的函数。对于 whereN
是 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*
文字在使用中可能具有欺骗性。
可变参数模板,自 4.5 起在 GCC 中可用,可进一步用于将每个模板的所有模板专业化样板代码简化为定义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 库?