有没有办法输入这个?

时间:2009-08-25 14:05:44

标签: c++ typedef

简化版代码:

foo.h中:

class Foo {
    private:
        class Bar {
            // ...
        };
        typedef std::map<int, Bar> mapType;
        mapType _map;
    public:
        void method(mapType::iterator it);
};

Foo.cpp中:

void Foo::method(mapType::iterator it) {
    // ...
    notMethod(it);
}

void notMethod(mapType::iterator it) {
    // ...
}

不出所料,我在'mapType' is not a class or namespace name的定义中得到了VS2008中的错误notMethod。是否有任何(优雅)方式可以避免在std::map<int, Bar>的定义中输入notMethod而不将notMethod转换为方法?

4 个答案:

答案 0 :(得分:20)

使用

void notMethod(Foo::mapType::iterator it) {
    // ...
}

并将typedef放在Foo的类声明的公共部分。

编辑:

如果你想避免这种情况,你可以

  1. notMethod成为朋友(由DanDan建议),
  2. 使用sbi的模板解决方案,或
  3. 使notMethod成为Foo的私有静态成员函数(生成的代码与免费的非成员函数完全相同)。
  4. 哪种解决方案最合适取决于notMethod的作用。

    如果notMethod使用BarBar实际上只在Foo内部实施的上下文中有意义,我会将notMethod设为私有静态成员函数,因为它是Foo内部的一部分。

    如果notMethod是一个需要非Foo作为其第一个参数的运算符(意​​味着它不能是Foo的成员),并且我想要为了保持Bar私密,我会让操作员成为朋友。

    如果notMethod在迭代器上实现泛型操作,我会把它变成模板函数。

    如果BarFoo客户可能感兴趣的类,我会将Bar和typedef公开并使用我最初建议的解决方案。

答案 1 :(得分:4)

Friends

添加

friend void notMethod(mapType::iterator it);

到您的Foo类,您可以保持内部类和函数的私密性。

答案 2 :(得分:4)

以Martin B的答案为基础:

notMethod 不知道类型 mapType 的原因是因为它在类 Foo 中,您可以将类视为在这种情况下,如果你想要名称空间

无论哪种方式,您都必须将代码更改为:

void notMethod(Foo::mapType::iterator it) {}

如果您同意Martin B,则必须将typedef移动到该类的 public 部分。如果您同意DanDan,则必须Friend该功能。

自己?我会将typedef放在类之外,并将class和typedef放入namespace

答案 3 :(得分:3)

Martin B has provided you with an answer。这是另一种选择:

你的notMethod()看起来像是一些实现细节,可能是在cpp文件的未命名命名空间中定义的。在这种情况下,我通常做的是使notMethod()成为模板:

template< typename It >
void notMethod(It it) {
    // ...
}

除了避免使typedef公开或使函数成为朋友之外,这还有一个额外的好处,即如果函数提供了一个有用的算法,你也可以用其他迭代器调用它。