如何查找被类成员函数遮蔽且需通过ADL解析的自由函数?
解决ADL被成员函数遮蔽的问题
问题代码
namespace some_namespace { struct the_type{}; void function(the_type); } namespace other_namespace { template<class T> class my_wrapper { public: void function() { function(m_value); } // 调用被成员函数遮蔽,无法触发ADL private: T m_value; }; }
问题描述
上述代码中,other_namespace::my_wrapper的成员函数function()尝试调用function(m_value),但该调用被成员函数自身遮蔽。目标自由函数位于模板参数T所属的未知命名空间中,无法直接使用命名空间限定符,希望通过ADL(参数依赖查找)找到该函数。是否只能通过在类外添加不同名称的包装函数解决此问题?
标准解决方案
不需要额外编写类外包装函数,以下几种符合C++标准的写法可以解决遮蔽问题,让ADL正常生效:
方法1:用括号消除成员函数的名字查找优先级
将调用语句改为(function)(m_value),括号会阻止编译器优先查找类成员函数,转而按照常规作用域规则查找,同时触发ADL匹配模板参数T所在命名空间的自由函数:
void function() { (function)(m_value); }
方法2:引入function名字到当前作用域
在成员函数内部添加using function;声明,将全局或其他作用域的function名字引入当前作用域,让编译器在查找时同时考虑ADL候选:
void function() { using function; function(m_value); }
注:如果全局作用域存在同名函数可能引发歧义,但针对依赖T的ADL场景,只要T所在命名空间的function参数匹配,就能正确选中目标函数。
方法3:使用辅助模板函数触发ADL
编写一个无同名成员的辅助模板函数,利用其作用域正常触发ADL:
namespace detail { template<typename T> void call_function(T&& val) { function(std::forward<T>(val)); } } // 在my_wrapper的function中调用 void function() { detail::call_function(m_value); }
辅助函数所在作用域没有遮蔽function的成员,因此调用时会自动通过ADL找到T所属命名空间的目标函数。
内容的提问来源于stack exchange,提问作者user877329
相关产品推荐
相关产品推荐

