C++ 朋友、模板、命名空间

C++ 朋友、模板、命名空间,c++,templates,c++17,friend,C++,Templates,C++17,Friend,我想要一个模板化的朋友函数。但是,我不知道如何使它在没有模板的函数中以相同的方式工作。 下面是一个示例代码 #include <iostream> namespace ns{ struct Obj { friend void foo(Obj){std::cout << "no problem" << std::endl;} template<typename T> friend void bar(Obj){std::co

我想要一个模板化的朋友函数。但是,我不知道如何使它在没有模板的函数中以相同的方式工作。 下面是一个示例代码

#include <iostream>

namespace ns{
struct Obj {
    friend void foo(Obj){std::cout << "no problem" << std::endl;}

    template<typename T>
    friend void bar(Obj){std::cout << "problem" << std::endl;}
};
}

int main() {
    ns::Obj obj;
    foo(obj); // Compile
    bar<int>(obj); // Not compile
    return 0;
}
#包括
名称空间ns{
结构对象{

friend void foo(Obj){std::cout在C++20之前,您需要教导编译器
bar
是模板的名称,以便它知道
简单的方法是添加一个正向声明,并使用限定查找来定位函数:

namespace ns{
struct Obj;

void foo(Obj);

template<typename T>
void bar(Obj);

struct Obj {
    friend void foo(Obj){std::cout << "no problem" << std::endl;}

    template<typename T>
    friend void bar(Obj){std::cout << "problem " << std::endl;}
};
} // namespace ns

int main() {
    ns::Obj obj;
    ns::foo(obj); // Ok
    ns::bar<int>(obj); // Ok
    return 0;
}
ns{
结构对象;
无效foo(Obj);
模板
空心钢筋(Obj);
结构对象{

福友德(Obj){std::cout related/dupe:@NathanOliver那里接受了哪一个答案很不幸……费萨尔的答案很好,但我更倾向于将这个答案作为这个答案的一个副本关闭。@Barry是的。我不久前发表了评论,但用户没有回应。@Barry我们可以删除这个答案,然后复制关闭或要求一个mod合并。我尝试了你的解决方案,但它失败了:以下是示例:@AntoineMorrier只要您使类版本返回为空,它就会成功:
template<class T>
struct type {};

namespace ns{
struct Obj {    
    // ...

    template<typename T>
    friend void bar(Obj, type<T>) { /* ... */ }
};
}
// ...

bar(obj, type<int>()); // OK
namespace ns{
struct Obj;

void foo(Obj);

template<typename T>
void bar(Obj);

struct Obj {
    friend void foo(Obj){std::cout << "no problem" << std::endl;}

    template<typename T>
    friend void bar(Obj){std::cout << "problem " << std::endl;}
};
} // namespace ns

int main() {
    ns::Obj obj;
    ns::foo(obj); // Ok
    ns::bar<int>(obj); // Ok
    return 0;
}