我有以下模板功能:
struct ms {
template <typename... Args>
void update(string& query, Args&... args);
};
template <typename... Args>
void ms::update(string& query, Args&... args)
{
const int size = sizeof...(args);
vector<string> vec = { args... };
for (int i = 0; i < size; ++i) {
cout << query << ": " << vec[i] << endl;
}
}
但是,我想消除模板的使用,只需使其成为一个带有一个或多个字符串参数的成员函数。关于Variadic函数的所有文档和示例我都可以找到使用字符数组并执行while指针!= null来获取数组中的每个值。
如果我这样做:
void update(string& query, string&... args);
如果有任何参数,我将如何迭代args参数?
答案 0 :(得分:1)
这是array_view<T>
:
template<class T>
struct array_view;
template<class D>
struct array_view_base;
template<class T>
struct array_view_base<array_view<T>> {
T* b=0; T* e=0;
T* begin() const { return b; }
T* end() const { return e; }
T& operator[](std::size_t i)const{ return begin()[i]; }
std::size_t size() const { return end()-begin(); }
T& front() const { return *begin(); }
T& back() const { return *(end()-1); }
array_view<T> without_front( std::size_t N=1 ) const {
N=(std::min)(N, size());
return {begin()+N, end()};
}
array_view<T> without_back( std::size_t N=1 ) const {
N=(std::min)(N, size());
return {begin(), end()-N};
}
array_view_base( T* s, T* f ):b(s),e(f){}
array_view_base( T* s, std::size_t sz ):array_view_base(s, s+sz) {}
template<std::size_t N>
array_view_base( T(&arr)[N] ):array_view_base(arr, N) {}
template<class C,
std::enable_if_t<!std::is_same<std::decay_t<C>, array_view<T>>{}, int> =0
>
array_view_base( C&& c ):array_view_base(c.data(), c.size()) {}
};
template<class T>
struct array_view:array_view_base<array_view<T>> {
using array_view_base<array_view<T>>::array_view_base;
};
template<class T>
struct array_view<T const>:array_view_base<array_view<T const>> {
using array_view_base<array_view<T const>>::array_view_base;
array_view( std::initializer_list<T> il ):array_view( std::addressof(*il.begin()), il.size() ) {}
};
它有点像gsl::span<T>
。它是T
的连续范围。
与gsl::span<T>
不同,array_view<T const>
可以从initializer_list<T>
构建。
使用它,您的代码应如下所示:
struct ms {
void update(string const& query, array_view<string const> args);
};
void ms::update(string const& query, array_view<string const> args)
{
for (int i = 0; i < args.size(); ++i) {
cout << query << ": " << args[i] << endl;
}
}
你称之为:
ms{}.update( "Hello", {"one", "two", "three"} );
更糟糕的是,只需选择std::vector<std::string>
。
通话时
ms{}.update( "Hello", {"one", "two", "three"} );
也有效。与我的解决方案不同,这会导致内存分配。