代码之家  ›  专栏  ›  技术社区  ›  Michael Kristofik

我可以使用私有嵌套结构编写函数吗?

  •  5
  • Michael Kristofik  · 技术社区  · 15 年前

    对于此类:

    class C
    {
        private:
            struct Foo
            {
                int key1, key2, value;
            };
            std::vector<Foo> fooList;
    };
    

    这里的想法是 fooList 可通过以下任一方式建立索引: key1 key2 在foo结构中。我正在尝试编写传递给的函数 std::find_if 所以我可以在 愚蠢的人 每把钥匙。但是我不能让它们编译,因为 Foo 在类中是私有的(它不是C接口的一部分)。 有没有办法不暴露 去世界其他地方?

    下面是一个无法编译的代码示例,因为 在我的班级里是私人的:

    struct MatchKey1 : public std::unary_function<Foo, bool>
    {
        int key;
        MatchKey1(int k) : key(k) {}
        bool operator()(const Foo& elem) const
        {
            return key == elem.key1;
        }
    };
    
    6 回复  |  直到 15 年前
        1
  •  2
  •   Michael Kristofik    15 年前

    我会这样做的。

    标题:

    class C
    {
    private:
        struct Foo
        {
            int index;
            Bar bar;
        };
    
        // Predicates used to find Notification instances.
        struct EqualIndex;
        struct EqualBar;
    
        std::vector<Foo> fooList;
    };
    

    资料来源:

    // Predicate for finding a Foo instance by index.
    struct C::EqualIndex : std::unary_function<C::Foo, bool>
    {
        EqualIndex(int index) : index(index) { }
        bool operator()(const C::Foo& foo) const { return foo.index == index; }
        const int index;
    };
    
    // Predicate for finding a Foo instance by Bar.
    struct C::EqualBar : std::unary_function<C::Foo, bool>
    {
        EqualBar(const Bar& bar) : bar(bar) { }
        bool operator()(const C::Foo& foo) const { return foo.bar == bar; }
        const Bar& bar;
    };
    

    用途:

    // Find the element containing the Bar instance someBar.
    std::vector<Foo>::iterator it = std::find_if(fooList.begin(),
                                                 fooList.end(),
                                                 EqualBar(someBar));
    
    if (it != fooList.end())
    {
        // Found it.
    }
    

    某种程度上。。。

        2
  •  2
  •   MaxGuernseyIII    15 年前

    对。使该函数成为 C 并封装 std::find_if 背后的方法 .

    以下是一个例子:

    #include "stdafx.h"
    #include <vector>
    #include <cassert>
    #include <algorithm>
    #include <iostream>
    
    class C
    {
        private:
            struct Foo
            {
                int key1, key2, value;
            };
    
            std::vector<Foo> fooList;
    
        struct Finder
        {
        private:
          int key1, key2;
    
        public:
          Finder(int k1, int k2)
          {
            key1 = k1;
            key2 = k2;
          }
    
          bool operator ()(Foo const& foo) const
          {
            return foo.key1 == key1 || foo.key2 == key2;
          }
        };
    
    public:
      C()
      {
        Foo foo1, foo2;
        foo1.key1 = 5;
        foo1.key2 = 6;
        foo1.value = 1;
        foo2.key1 = 7;
        foo2.key2 = 8;
        foo2.value = 10;
    
        fooList.insert(fooList.begin(), foo1);
        fooList.insert(fooList.begin(), foo2);
      }
    
      int Find(int key1, int key2)
      {
        return std::find_if(fooList.begin(), fooList.end(), Finder(key1, key2))->value;
      }
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      C c;
    
      std::cout << c.Find(5, 3) << std::endl;
      std::cout << c.Find(3, 6) << std::endl;
      std::cout << c.Find(7, 3) << std::endl;
      std::cout << c.Find(3, 8) << std::endl;
    
      return 0;
    }
    
        3
  •  1
  •   Björn Pollex    15 年前

    你可以让函数成为 C .

        4
  •  1
  •   Michael Kristofik    15 年前

    语法很巴洛克式,但我可以 fooList 变成一个 boost::multi_index_container 索引于 key1 key2 .

        5
  •  0
  •   pmr    15 年前

    如果不需要在头中使用结构,也可以在实现文件中使用未命名的命名空间,将定义和声明设置为编译单元的本地(静态是类C的替代方法 static )

    这将为您留下一个不被实现细节所掩盖的更清晰的头。

        6
  •  0
  •   Michael Kristofik    15 年前

    我可以用 Pimpl Idiom 隐藏的私有部分 C 在另一个类中。因为一切都在 CImpl 可以安全地公开,我应该可以做任何我想做的事 Foo 那里。