我有以下模板功能:
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;
}
}
但是,我想消除模板的使用,而只是使它成为一个接受一个或多个字符串参数的成员函数。我可以找到有关可变参数函数的所有文档和示例,这些示例和示例显示了字符数组的用法,并做了一个while指针!= null来获取数组中的每个值。
如果我做类似的事情:
void update(string& query, string&... args);
如果有的话,我将如何遍历args参数?
最佳答案
这是一个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"} );
Live example。
作为更糟糕的示例,只需采用
std::vector<std::string>
即可。通话时
ms{}.update( "Hello", {"one", "two", "three"} );
也可以。与我的解决方案不同,这会导致内存分配。
关于c++ - 如何在不使用模板的情况下将可变参数函数与字符串一起使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46006690/