我有一个函数,我有这样的重载:
void process(const std::string& text)
{
}
void process(const std::vector<std::string>& manyTexts)
{
}
我称之为:
process({"hello", "hey"});
我希望这可以解决第二次重载,但这显然是模棱两可的。令我惊讶的是我发现这个要编译:
std::string text = {"hello", "hey"};
变量只包含&#39;你好&#39;这似乎没有用,也不直观。
有了这个,我有两个问题:
std::string
的有效初始化程序? 答案 0 :(得分:5)
std::string
有一个构造函数:
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
电话
std::string text = {"hello", "hey"};
解析为该构造函数。即使语法上调用解析为有效的构造函数,这也会导致运行时的未定义行为,因为"hello"
和"hey"
是不相关的字符串。
制作
的唯一方法process({"hello", "hey"});
解决第二个功能就是明确它。
process(std::vector<std::string>{"hello", "hey"});
答案 1 :(得分:1)
我回来了。我没有解决您的问题,而是暴露了process( std::experimental::span<const std::string> )
重载。
请参阅std::experimental::array_view
,其中较弱的版本易于编写。
大部分工作都在你想要的长长的名单中:
template<class T>
struct span {
T* b = nullptr;
T* e = nullptr;
T* begin() const { return b; }
T* end() const { return e; }
bool empty() const { return begin()==end(); }
std::size_t size() const { return end()-begin(); }
T& front() const { return *begin(); }
T& back() const { return *std::prev(end()); }
// extra useful things I have added in my version:
span without_front(std::size_t N=1) const {
return {begin()+(std::min)(size(), N), end()};
}
span without_back(std::size_t N=1) const {
return {begin(), end()-(std::min)(size(), N)};
}
// ctors: span uses "pointer semantics":
span()=default;
span(span const&)=default;
span& operator=(span const&)=default;
~span()=default;
// useful ctors for making a span:
span( T* s, T* f ):b(s), e(f) {}
span( T* s, std::size_t len ):span(s, s+len) {}
using non_const_T = std::remove_const_t<T>;
template<class A>
span( std::vector<T, A>& in ):span(in.data(), in.size()) {}
template<class A>
span( std::vector<non_const_T, A> const& in ):span(in.data(), in.size()) {}
template<class Traits>
span( std::string<T, Traits>& in ):span(in.data(), in.size()) {}
template<class Traits>
span( std::string<non_const_T, Traits> const& in ):span(in.data(), in.size()) {}
template<std::size_t N>
span( std::array<T, N>& in ):span(in.data(), in.size()) {}
template<std::size_t N>
span( std::array<non_const_T, N>const& in ):span(in.data(), in.size()) {}
template<std::size_t N>
span( T(&in)[N] ):span(in.data(), in.size()) {}
span( std::initializer_list<non_const_T> in ):span(in.begin(), in.size()) {}
};
这消除了vector
实施中不必要的分配。
这使得单字符串版本毫无意义。
void process(span<const std::string> texts)
{
for (const std::string& text:texts) {
// process one element
}
}
使用字符串调用,执行process({"bob"})
。对于字符串s
,请执行process({s})
。要使用向量v进行调用,请执行process(v)
。
工业品质span
只有process(non_const_T)
的{{1}}样式构造函数,但我很懒惰。