简化版代码:
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
转换为方法?
答案 0 :(得分:20)
使用
void notMethod(Foo::mapType::iterator it) {
// ...
}
并将typedef放在Foo
的类声明的公共部分。
编辑:
如果你想避免这种情况,你可以
notMethod
成为朋友(由DanDan建议),notMethod
成为Foo
的私有静态成员函数(生成的代码与免费的非成员函数完全相同)。哪种解决方案最合适取决于notMethod
的作用。
如果notMethod
使用Bar
而Bar
实际上只在Foo
内部实施的上下文中有意义,我会将notMethod
设为私有静态成员函数,因为它是Foo
内部的一部分。
如果notMethod
是一个需要非Foo
作为其第一个参数的运算符(意味着它不能是Foo
的成员),并且我想要为了保持Bar
私密,我会让操作员成为朋友。
如果notMethod
在迭代器上实现泛型操作,我会把它变成模板函数。
如果Bar
是Foo
客户可能感兴趣的类,我会将Bar
和typedef公开并使用我最初建议的解决方案。
答案 1 :(得分:4)
答案 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
公开或使函数成为朋友之外,这还有一个额外的好处,即如果函数提供了一个有用的算法,你也可以用其他迭代器调用它。