假设我正在编写一个函数来打印字符串的长度:
template <size_t N>
void foo(const char (&s)[N]) {
std::cout << "array, size=" << N-1 << std::endl;
}
foo("hello") // prints array, size=5
Run Code Online (Sandbox Code Playgroud)
现在我想扩展foo以支持非数组:
void foo(const char* s) {
std::cout << "raw, size=" << strlen(s) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但事实证明,这破坏了我原来的预期用途:
foo("hello") // now prints raw, size=5
Run Code Online (Sandbox Code Playgroud)
为什么?这不需要数组到指针的转换,而模板是完全匹配的吗?有没有办法确保我的数组函数被调用?
在这个答案中,我们可以看到我们可以创建自己的views. 我试过了:
template <typename Range>
struct squared_view : std::ranges::view_interface<squared_view<Range>> {
struct iterator;
constexpr squared_view() = default;
constexpr squared_view(Range t): t(t) { }
auto begin() const { return iterator(std::ranges::begin(t)); }
auto end() const { return iterator(std::ranges::end(t)); }
Range t;
};
template <typename Range>
struct squared_view<Range>::iterator {
using value_type = typename std::ranges::iterator_t<Range>::value_type;
constexpr iterator() = default;
constexpr iterator(std::ranges::iterator_t<Range> it): it_{it} { }
iterator& operator++() {
++it_;
return *this;
}
iterator operator++(int) {
const iterator current{*this};
++it_;
return current; …Run Code Online (Sandbox Code Playgroud)