限制 class 的模板好友

Restrict template friends of a class

考虑以下代码:

#include <iostream>

class S {
    static const int i = 42;
    template <class T>
    friend void f();
};

template <class T>
void f()
{
    std::cout << S::i << "\n";
}

int main() 
{
    f<int>();
    f<double>();
}

我在这里只想允许访问 class Sf<int> 的私有部分,但不允许访问 f<double>。 IE。我想得到 f<double>() 行的 'i' is a private member of 'S' 之类的编译器错误。

如何实现?

模板实例化是一个函数,所以命名为:void f<int>().

不过你需要事先声明:

[C++03: 11.4/9 | C++11/C++14: 11.3/11]: If a friend declaration appears in a local class (9.8) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. [..]

(这不是您最初拥有的 friend-inside-template-declaration 的情况,因为稍后会在解析过程中查找模板。)

这是完成的解决方案:

#include <iostream>

template <class T>
void f();

class S {
    static const int i = 42;
    friend void f<int>();
};

template <class T>
void f()
{
    std::cout << S::i << "\n";
}

int main() 
{
    f<int>();
    f<double>();
}

现在唯一的错误是由 f<double>() 调用引起的。

(live demo)

您需要在 class S 之前声明(或定义)模板函数。然后你可以直接说你想让它和f<int>()成为朋友。像这样:

template <class T> void f();

class S {
    static const int i = 42;
    friend void f<int>();
};

template <class T>
void f()
{
    std::cout << S::i << "\n";
}