【问题标题】:Projection: Is it OK to take address of data member of STL container?Projection: Is it OK to take address of data member of STL container?
【发布时间】: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 member you are not taking pointer to container member, you are passing a pointer to member of std::pair. This is well defined. This is exactly same thing as this: godbolt.org/z/GrGEEYEWv

标签: c++ projection


【解决方案1】:

The only restrictions I see in [namespace.std] are about pointers to memberfunctions. I can't find anything that would disallow taking a pointer to a (public) data member of a standard library class.

This also makes sense, since the restrictions forfunctionsare there to allow the standard library implementation to choose a different overload set than described in the standard, as long as direct calls still work as specified. However, there is no similar choice the implementation could make for a data member that is specified in the public interface (not for exposition only).

So I don't see anything wrong with &amp;Counter::value_type::second.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-26
    • 2022-12-27
    • 2022-12-27
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2022-12-27
    相关资源
    最近更新 更多