是否可以将友元函数声明为静态?

时间:2013-11-07 19:58:58

标签: c++ static friend

以下是一些编译和工作正常的C ++示例代码:

class A
{
public:
   A() {/* empty */}

private:
   friend void IncrementValue(A &);
   int value;
};

void IncrementValue(A & a)
{
   a.value++;
}   

int main(int, char **)
{
   A a;
   IncrementValue(a);
   return 0;
}

然而,我想要做的是将IncrementValue()声明为static,以便无法从另一个编译单元看到或调用它:

static void IncrementValue(A & a)
{
    a.value++;
}

然而,这样做会给我一个编译错误:

temp.cpp: In function ‘void IncrementValue(A&)’:
temp.cpp:12: error: ‘void IncrementValue(A&)’ was declared ‘extern’ and later ‘static’
temp.cpp:8: error: previous declaration of ‘void IncrementValue(A&)’

...并将好友声明更改为匹配无效:

friend static void IncrementValue(A &);

...因为它给出了这个错误:

temp.cpp:8: error: storage class specifiers invalid in friend function declarations

我的问题是,在C ++中有没有办法让一个声明为静态的(非方法)友元函数?

2 个答案:

答案 0 :(得分:22)

引用N3691 - §11.3/ 4 [class.friend]

  

首先在朋友声明中声明的函数具有外部链接(3.5)。否则,该函数将保留其先前的链接(7.1.1)。

因此,在将声明为static之前,您需要将该函数声明为friend 。这可以通过在A的定义之上添加以下声明来完成。

class A;  // forward declaration, required for following declaration
static void IncrementValue(A&); // the friend declaration will retain static linkage

答案 1 :(得分:16)

不确定。仔细阅读错误消息的第二行:函数已声明为extern稍后 static。所以你要做的就是在朋友声明之前将它声明为静态:

class A;
static void IncrementValue(A&);

class A {
    // class definition, including friend declaration
};

static void IncrementValue(A&) {
    // code here, of course
}