类模板的函数模板友元声明问题:限定get模板实例为any_of友元
问题:限制函数模板get为类模板any_of的特定友元实例
我希望将函数模板get()声明为类模板any_of的友元,但仅允许与any_of拥有相同类型参数的get模板实例成为其友元,索引I不可自由取值。例如,所有get<N, char, char>实例应为any_of<char, char>的友元,但不能是any_of<int, char>的友元。
尝试的错误代码
#include <tuple> #include <utility> template<typename T, typename... TT> struct any_of; template<auto I, typename... TT> auto& get(const any_of<TT...>&); template<typename T, typename... TT> struct any_of { template<auto I> friend auto& get<I, T, TT...>(const any_of<T, TT...>&); any_of(const T& first, const TT&... rest) : mData{first, rest...}{} private: std::tuple<T, TT...> mData; }; template<auto I, typename... TT> auto& get(const any_of<TT...>& a) { return std::get<I>(a.mData); } template<typename L, typename... TT> bool operator==(const L& lhs, const any_of<TT...>& rhs) { return [&]<auto... II>(std::index_sequence<II...>){ return ((lhs == get<II>(rhs)) || ...); }(std::make_index_sequence<sizeof...(TT)>{}); }
编译错误信息
invalid use of template-id 'get<I, T, TT ...>' in declaration of primary template
解决方案
错误原因
原代码的友元声明写法不符合C语法:在友元声明中直接使用带实参的模板id(get<I, T, TT...>)来声明友元模板是不允许的,C要求友元模板声明必须匹配已有的模板声明,不能在此处直接指定部分模板实参。
修正后的代码
#include <tuple> #include <utility> // 前置声明any_of模板 template<typename... TT> struct any_of; // 前置声明get函数模板 template<auto I, typename... TT> auto& get(const any_of<TT...>&); template<typename T, typename... TT> struct any_of { // 正确的友元声明:绑定当前类的类型参数,仅允许对应类型的get<I>实例访问私有成员 template<auto I> friend auto& get<I, T, TT...>(const any_of<T, TT...>&); any_of(const T& first, const TT&... rest) : mData{first, rest...}{} private: std::tuple<T, TT...> mData; }; // get函数模板的定义 template<auto I, typename... TT> auto& get(const any_of<TT...>& a) { return std::get<I>(a.mData); } // 修复operator==中的索引序列长度问题:any_of<T, TT...>的tuple包含1+sizeof...(TT)个元素 template<typename L, typename... TT> bool operator==(const L& lhs, const any_of<TT...>& rhs) { return [&]<auto... II>(std::index_sequence<II...>){ return ((lhs == get<II>(rhs)) || ...); }(std::make_index_sequence<1 + sizeof...(TT)>{}); }
说明
修正后的友元声明通过绑定当前any_of实例的类型参数T, TT...,确保只有对应类型的get<I>模板实例能访问any_of的私有成员mData,同时保留I作为可变的非类型模板参数,满足索引取值的需求。另外修复了operator==中索引序列长度错误的问题,避免了数组越界风险。
内容的提问来源于stack exchange,提问作者wimalopaan
相关产品推荐
相关产品推荐

