如何将友元函数存储到std::function中?
问题原因
C++标准对友元声明的可见性有特殊规定:仅在类内部声明的友元函数,不会自动将函数名注入到外围命名空间作用域。仅当满足以下两种情况时,该函数才可被正常查找:
- 访问位置在友元声明所在的类内部
- 触发参数依赖查找(ADL),即函数参数包含该类类型的实例
你提供的代码中,foo的参数是int,无法触发针对SomeClass的ADL,且访问位置在OtherClass内部,不属于SomeClass的作用域,自然找不到foo的声明。而foobar已经在全局作用域显式声明,所以可以正常查找。
解决方案
最简单的解决方式是在类外部的对应作用域,额外补充一次foo的声明:
#include <functional> // 全局作用域显式声明foo,补充友元声明的可见性 bool foo(int arg); class SomeClass { public: friend bool foo(int arg); }; bool foobar(int); class OtherClass { public: void bar(){ std::function<bool(int)> f; f = foo; // 此时可以正常找到foo的声明 std::function<bool(int)> g; g = foobar; } }; // 后续实现foo即可,实现时依然可以正常访问SomeClass的私有/保护成员 bool foo(int arg) { // 业务逻辑 return arg > 0; }
如果不希望foo污染全局命名空间,也可以将foo和SomeClass放在同一个自定义命名空间下,仅在该命名空间范围内补充声明即可。
内容的提问来源于stack exchange,提问作者infinitezero
相关产品推荐
相关产品推荐

