我有以下类(class):
template<int P>
struct A {
struct B {
auto abs() const { return 1; }
};
};
特别是A
应该是整数模 P 的有限域,并且 B
是表示来自该有限域的元素的类。然后我有一个扩展 GCD 算法的通用实现,它应该使用 abs
功能。我希望扩展的 GCD 算法实现能够处理基本类型(int、long 等)以及 A<P>::B
的问题.所以我需要实现一个非成员 abs
那会调用A<P>::B::abs
.我尝试了三种技术,其中两种不起作用,一种起作用但不适合。
技术 1(不起作用):使用参数相关查找 (ADL)。在 A
的内部定义以下内容|但在 B
的主体之外:
auto abs(B const &e) { return e.abs(); }
它不会工作,因为 ADL 只在命名空间内部查找,而不是在类范围内查找。 更新:ADL 在这里不起作用,因为 abs
是一个实例方法。但是,根据 T.C. 的回答,如果您将它设为友元函数,它会正常工作并且 ADL 会找到它!
技巧 2(不起作用):在全局或命名空间范围内使用约束函数模板:
template<int P>
auto abs(typename A<P>::B const &e) { return e.abs(); }
这也行不通,因为 P
处于非推导上下文中。
技术 3(有效,但不令人满意):在全局或命名空间范围内使用不受约束的函数模板:
template<typename T>
auto abs(T const &e) { return e.abs(); }
这行得通。然而,它是不受约束的。我想将此函数模板的实例化限制为 A<P>
(对于 P
事先未知)和其他类模板(用于多项式环和字段扩展)。问题是如果 P
我不确定如何使用 SFINAE处于非推导上下文中。
最佳答案
template<int P>
struct A {
struct B {
auto abs() const { return 1; }
};
friend auto abs(B const &e) { return e.abs(); }
// ^^^^^^
};
然后让 ADL 发挥它的魔力。
(在 B
中定义它也可以。选择取决于您。)
关于c++ - 为类模板的特定嵌套类实现非成员泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37311331/