简体   繁体   English

Clang 错误:不支持朋友 class 声明的相关嵌套名称说明符

[英]Clang error: Dependent nested name specifier for friend class declaration not supported

I am trying to write a hash function for my custom class, and make my code compatible with both gcc 11.1 and clang 12.0.0, but clang gives the warning/error: I am trying to write a hash function for my custom class, and make my code compatible with both gcc 11.1 and clang 12.0.0, but clang gives the warning/error:

<source>:30:25: warning: dependent nested name specifier 'std::hash<Base<U>>::' for friend class declaration is not supported; turning off access control for 'Base' [-Wunsupported-friend]
    std::hash<Base<U>>::operator()(const Base<U>& b) const noexcept;

<source>:38:26: error: 'data_' is a private member of 'ns::Base<int>'
    std::size_t seed = b.data_.size();

for the code below (also at https://godbolt.org/z/8Wsnqr5cb ).对于下面的代码(也在https://godbolt.org/z/8Wsnqr5cb )。 How can I fix it to be compatible with both?如何修复它以与两者兼容?

#include <set>
#include <utility>
#include <iostream>

// Forward declaration    
namespace ns
{
    template<typename T>
    class Base;
}

/// Hash specialization declaration
template<typename T>
struct std::hash<ns::Base<T>>
{
    std::size_t operator()(const ns::Base<T>& b) const noexcept;
};

namespace ns
{

template<typename T>
class Base {
    std::set<T> data_;

    public:
    Base(const std::set<T>& data): data_{data} {}

    template<typename U>
    friend std::size_t 
    std::hash<Base<U>>::operator()(const Base<U>& b) const noexcept;
};

}

// In implementation file:
template<typename T>
std::size_t std::hash<ns::Base<T>>::operator()(const ns::Base<T>& b) const noexcept
{
    std::size_t seed = b.data_.size();
    for(const auto & x : b.data_)
        seed ^= x;
    return seed;
}


using namespace ns;

int main()
{
    std::set<int> data({1,2,3,4,5});

    Base<int> a(data);

    std::cout << std::hash<Base<int>>{}(a) << std::endl;
}

You can change the friend declaration only valid for the Base of current template parameter T , ie current instantiation.您可以更改仅对当前模板参数TBase有效的friend声明,即当前实例化。

template<typename T>
class Base {
    std::set<int> data_;

    public:
    Base(const std::set<int>& data): data_{data} {}

    friend std::size_t 
    std::hash<Base<T>>::operator()(const Base<T>& b) const noexcept;

    //or just
    //friend std::size_t 
    //std::hash<Base>::operator()(const Base& b) const noexcept;
};

Note that the effect is different with yours.请注意,效果与您的不同。 With the above friend declaration, for example, given Base<int> , only std::hash<Base<int>>::operator() is the friend .例如,对于上面的friend声明,给定Base<int> ,只有std::hash<Base<int>>::operator()friend With template friend declaration in your code, given Base<int> , all the possible instantiations like std::hash<Base<int>>::operator() , std::hash<Base<char>>::operator() , ... are friend s.在代码中使用模板friend元声明,给定Base<int> ,所有可能的实例化,如std::hash<Base<int>>::operator()std::hash<Base<char>>::operator() , ... 是friend

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

相关问题 错误:声明的嵌套名称说明符未引用到 class、class 模板或 class 模板部分专业化 - error: nested name specifier for declaration does not refer into a class, class template or class template partial specialization 头文件类成员函数声明错误:“嵌套名称说明符中的类型不完整&#39;&#39;名称” - Header file class member function declaration error: “incomplete type ' ' name in nested name specifier” 友元函数声明中的内联说明符 - inline specifier in a friend function declaration 以嵌套类作为参数的朋友模板声明 - Friend template declaration with nested class as argument 错误“此声明没有存储类或类型说明符” - Error “this declaration has no storage class or type specifier” C++ 已知 class 名称嵌套在任何其他名称中的模板友元声明 - C++ template friend declaration for known class name nested in any other 在elaborated-type-specifier中依赖于类型的嵌套名称说明符 - type-dependent nested-name-specifier in elaborated-type-specifier 编译器错误预期嵌套名称说明符 - compiler error expected nested-name specifier 错误:嵌套名称说明符中使用的类型不完整 - Error: incomplete type used in nested name specifier 错误:类型不完整…在嵌套名称说明符中使用 - error: incomplete type … used in nested name specifier
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM