我现在想制作模板,将一些元素推送到支持push_back
运算符的向量和其他类型。
我可以这样做
template<typename T>
T fill(size_t n) {
T v;
//(1)
for(size_t i = 0; i < n; ++i){
v.push_back(generate_some_how());
}
return v;
}
有效。但现在我想使用v.reserve(n);
代替(1)
来提高支持它的类型的速度。但我仍然希望能够为不能编译reserve
这是实现这个目标的简单方法吗?
我知道我可能会专注于硬编码类型,但它看起来并不好。
C ++ 11没问题。
答案 0 :(得分:8)
使用C ++ 11的简单示例:
template<class T>
auto maybe_reserve(T& v, size_t n, int)
-> decltype(v.reserve(n), void())
{
v.reserve(n);
}
template<class T>
void maybe_reserve(T&, size_t, long){}
template<typename T>
T fill(std::size_t n) {
T v;
maybe_reserve(v, n, 0);
for(size_t i = 0; i < n; ++i){
v.push_back(generate_some_how());
}
return v;
}
Live example.有关解释,请查看here。
答案 1 :(得分:6)
C ++ 11中的一种可能方法:
template<typename T, typename = void>
struct reserve_helper
{ static void call(T& obj, std::size_t s) { } };
template<typename T>
struct reserve_helper<T, decltype(std::declval<T>().reserve(0), void(0))>
{ static void call(T& obj, std::size_t s) { obj.reserve(s); } };
template<typename T>
T fill(std::size_t n)
{
T v;
reserve_helper<T>::call(v, 10);
for(std::size_t i = 0; i < n; ++i){
v.push_back(generate_somehow());
}
return v;
}
以下是 live example ,显示只使用未定义任何reserve()
成员函数的UDT跳过对reserve()
的调用。
答案 2 :(得分:2)
不太难....你需要编写一个特征,用正确的签名检测保留成员函数的存在。使用该工具有不同的方法,您可以编写一个reserve_
模板函数,该函数使用该特征调度到reserve()
或无操作的调用,并从{{1或者你可以在助手或// (1)
本身使用SFINAE。我会尝试使用辅助函数,因为填充中的大多数代码都是相同的。
检测C ++ 03中是否存在fill
成员函数:
void reserve(std::size_t)