【发布时间】:2015-11-02 15:05:58
【问题描述】:
我们在代码库中观察到一个令人惊讶的行为,即未能应用友谊关系。 (目前仅使用 Clang 3.6 版编译)
我们可以将其简化为这个最小的示例。假设我们有以下模板类定义:
template <int>
class Element
{};
// Forward declaration of FriendBis
template <template <int> class> class FriendBis;
class Details
{
friend class FriendBis<Element>;
int mValue = 41;
};
template <template <int> class>
class FriendBis
{
public:
void useDetails(const Details &aDetails)
{
aDetails.mValue;
}
};
这里,Details 声明 FriendBis 的实例化,其单个模板模板参数替换为 Element 是它的 friend。因此,以下客户端代码编译成功:
FriendBis<Element> fb1;
fb1.useDetails(Details());
问题
现在,让我们介绍额外的trait 模板类型,其全部目的是将proto 定义为Element 模板的模板别名:
struct trait
{
template <int N>
using proto = Element<N>;
};
下面的客户端代码无法编译:
FriendBis<trait::proto> fb2;
fb2.useDetails(Details());
这让我们感到惊讶,因为trait::proto 是Element 的别名,但一个可以编译而另一个不能编译。
- 这是预期的行为吗?
- 如果是这样,这个限制的理由是什么?
- 有解决方法吗? (同时保持有限的友谊,而不是将
FriendBis的所有实例化为朋友)。
【问题讨论】:
-
这是相关的:stackoverflow.com/a/30654483/4326278。也许那里的细节会有所帮助。
标签: c++ templates c++11 friend