【发布时间】:2022-12-01 14:03:01
【问题描述】:
Let's take (as a demo example) a simple counting algorithm for getting the max count of characters in a string.
A typical C++17 implementation could be:
#include <iostream>
#include <unordered_map>
#include <string_view>
#include <algorithm>
#include <utility>
using Counter = std::unordered_map<char, std::size_t>;
using Pair = Counter::value_type;
constexpr std::string_view s{ "abbcccddddeeeeeffffff" };
int main() {
Counter counter{};
for (const char c : s) counter[c]++;
const auto& [letter, count] = *std::max_element(counter.begin(), counter.end(),
[](Pair& p1, Pair& p2) { return p1.second < p2.second; });
std::cout << "\n\nHighest count is '" << count << "' for letter '" << letter << "'\n\n";
}
In C++20 we have projections and can use pointer to structure member elements for the projection (and give that to the underlying std::invoke).
The solution would be a little bit shorter, not sure, if better (for whatever criteria). Anyway:
#include <iostream>
#include <unordered_map>
#include <string_view>
#include <algorithm>
using Counter = std::unordered_map<char, std::size_t>;
namespace rng = std::ranges;
constexpr std::string_view s{ "abbcccddddeeeeeffffff" };
int main() {
Counter counter{};
for (const char c : s) counter[c]++;
const auto& [letter, count] = *rng::max_element(counter, {}, &Counter::value_type::second);
std::cout << "\n\nHighest count is '" << count << "' for letter '" << letter << "'\n\n";
}
But, Im not sure about taking the address of a containers data member, residing in the std::namespace. Is this OK?
【问题讨论】:
-
I am not sure about eel.is/c++draft/namespace.std#6
-
perhaps better mention pointer to member somewhere in the text. I had to read twice to understand what the question is about
-
This is perfectly fine. Projection uses pointer just as indication which value you are interested in. It doesn't have to be pointer to member it can be lambda or function which accepts pair and returns something. I do not understudy where your doubts came from.
-
@MarekR using pointers to functions looks similarly innocent, but is not allowed for most standard functions (unless they are explicitly addressable functions), i suppose thats where the doubts come from. But yes, the question would be much clearer if the question would mention a reason why it wouldnt be ok
-
Quote:
Im not sure about taking the address of a containers data memberyou are not taking pointer to container member, you are passing a pointer to member ofstd::pair. This is well defined. This is exactly same thing as this: godbolt.org/z/GrGEEYEWv
标签: c++ projection