繁体   English   中英

将类的模板化友元函数作为参数传递给其他函数会导致错误

[英]Passing templated friend function of a class to other function as parameter results in error

下面的代码演示了这个问题。

#include <functional>

namespace test {

template <class T>
class A {
   public:
    friend auto foo(const A& obj) { return 1; }
};

template <class Function, class... Args>
void bar(Function f, Args&&... args) {
    const auto result = std::invoke(f, std::forward<Args>(args)...);
    // do stuff with result
}

}  // namespace test

auto main() -> int {
    test::A<int> value;
    test::bar(foo<int>, value);  // results in compile time error
    test::bar(test::foo<int>, value);  // results in compile time error
    return 0;
}

这是编译器资源管理器的此处链接

它可能与依赖于参数的查找有关,但我无法真正理解它。

问题是您提供的foo朋友声明是针对非模板函数的,但是在调用 bar 时,您试图将foo用作模板。

有两种方法可以解决这个问题:

方法一

在这里,我们为foo提供了一个单独的参数子句。

namespace test 
{
   
    template <class T> class A {
    public:
        template<typename U> //separate parameter clause added here
        friend auto foo(const A<U>& obj);
    };
//definition
template<typename U>
auto foo(const A<U>& obj) { return 1; }
    
template <class Function, class... Args>
void bar(Function f, Args&&... args) {
    const auto result = std::invoke(f, std::forward<Args>(args)...);
        // do stuff with result
    }

}  // namespace test

auto main() -> int {
    test::A<int> value;
    test::bar(test::foo<int>, value);  //works
    return 0;
}

工作演示

方法二

这里我们为函数模板foo提供了一个前向声明,然后在类之外定义它。

namespace test 
{
    //forward declarations
    template <class T> class A;
    template<typename TT> auto foo(const A<TT>& obj);

    template <class T> class A {
    public:
        //friend declaration
        friend auto foo<>(const A& obj);
//---------------------^^---------------->note the angle brackets
    };
//definition
template<typename TT>
auto foo(const A<TT>& obj) { return 1; }
    
template <class Function, class... Args>
void bar(Function f, Args&&... args) {
    const auto result = std::invoke(f, std::forward<Args>(args)...);
        // do stuff with result
    }

}  // namespace test

auto main() -> int {
    test::A<int> value;
    test::bar(test::foo<int>, value);  //works
    return 0;
}

工作演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM