【问题标题】:Friend Function name undefined朋友函数名称未定义
【发布时间】:2021-10-13 15:47:39
【问题描述】:

我尝试将朋友函数名称 comp 传递给 set_intersection,在 Visual Studio 2019 中编译时出现编译错误:E0020 标识符“comp”未定义

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Test {
    friend bool comp(const Test& A, const Test& B) { return A.a < B.a; }
public: 
    int a{ 10 };
};

int main() {
    vector<Test> v1{ Test{} };
    vector<Test> v2{ Test{} };
    vector<Test> rs;

    set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(rs), comp);
}

但是,如果我将 comp 更改为 operator&lt;,它可以与 set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(rs)); 正常工作。为什么comp 不起作用?

【问题讨论】:

    标签: c++ friend


    【解决方案1】:

    comp 在此处无法查找。对于friend declaration

    在类或类模板 X 中的友元声明中首先声明的名称成为 X 的最内层封闭命名空间的成员,但对于查找不可见(除了考虑 X 的参数相关查找),除非在提供了命名空间范围

    (请注意,ADL 仅适用于函数调用表达式,即comp(...);。)

    您需要在全局命名空间中提供声明。

    bool comp(const Test& A, const Test& B);
    class Test {
        friend bool comp(const Test& A, const Test& B) { return A.a < B.a; }
    public: 
        int a{ 10 };
    };
    
    int main() {
        vector<Test> v1{ Test{} };
        vector<Test> v2{ Test{} };
        vector<Test> rs;
    
        set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(rs), comp);
    }
    

    【讨论】:

    • 即使没有在全局命名空间中声明,comp(v1[0], v2[0]); 仍然有效,我认为 ADL 使这成为可能,对吧?但是为什么 ADL 在 set_intersection 函数调用中不起作用?
    • @Neymar87 ADL 仅适用于函数调用表达式,即comp(...);
    • 但是为什么 operator
    • @Neymar87 会被set_intersection调用,ADL生效。如果你只是把它称为operator&lt;,它也找不到。
    • @Neymar87 问题是compset_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(rs), comp);中的使用,名称comp找不到。如果你使用operator&lt; 而不是像set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(rs), operator&lt;);,它也不起作用。
    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 2016-05-29
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多