c++ - 为类模板的特定嵌套类实现非成员泛型函数

标签 c++ templates inner-classes argument-dependent-lookup name-lookup

我有以下类(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/

相关文章:

c++ - "required from here"声明列表列表时出错

java - Java 中嵌套类的目的是什么?

java - 了解 Java 内部类中的作用域

c++ - 为什么不能为冒泡排序设置一个循环?

c++ - ltrace: 在 "library.so"中找不到 .dynsym 或 .dynstr

c++程序来监视目录的更改

c++ - 为什么模板编译这么慢?

c++ - 无法在Windows上使用mingw将sqlite3与c连接

c++ - 这是一个好的设计选择吗?

java - 外部类可以访问内部类的成员吗?