我有以下情况。我在自己的命名空间foo
中有一个类my_lib
:
namespace my_lib{
template<typename T>
class foo{
T data;
public:
// blah blah
};
}
我正在尝试与另一个拥有自己的命名空间other_lib
的库进行交互。我将此接口放在我自己wrapper
的{{1}}命名空间中。特别是我的复制方法my_lib
我需要访问my_lib::wrapper::copy
所以我需要实现以下内容:
my_lib::foo::data
要完成此namespace my_lib{
namespace wrapper{
template<typename T>
void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo)
{
// copy my_foo.data to other_foo
}
}
}
方法,需要成为my_lib::wrapper::copy
类的朋友。我可以通过my_lib::foo
foo.h
这有效,但我不喜欢它。首先,它为一个与// forward declare other_lib::foo
namespace other_lib{
template<typename T>
class foo;
}
namespace my_lib{
// forward declare wrapper::copy
namespace wrapper{
template<typename T>
void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo);
}
template<typename T>
class foo{
T data;
friend void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo);
public:
// blah blah
};
}
和other_lib
命名空间无关的文件添加了大量内容。此外,在我的代码中使用其他库是可选的,但如果有人包含wrapper
,他们将会看到所有类型的无关前向声明,并开始想知道为什么......
如何修复此设计?
答案 0 :(得分:2)
让friend
除了其他名称空间之外的句法技巧,正确的方法是修复你的设计。如果需要在一些完全不相关的命名空间朋友访问中授予copy()
函数,则foo的接口为simply not complete。
一种方法是将copy()
置于foo
(以及foo用户需要的任何其他算法)中。如果做得好,这将导致一个完整且可用的课程foo
。例如。查看具有自己的sort()
成员函数的std::list
,以利用列表实现细节。但是,这可能很快导致foo
的膨胀类接口(只需查看std::string
),因此不建议将其作为一般规则。
或者,您可以提供一组最小的数据访问成员函数(最好是迭代器,而不是原始数据的句柄),以便其他类可以实现适用于foo
的算法。使用常规容器(数组,向量等)作为foo
内的数据表示,这将是我对一般用途的建议。
但是,由于您的类foo
有一个棘手的稀疏矩阵表示,您应该首先尝试使用algorithm-as-members-approach。