You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类模板的函数模板友元声明问题:限定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:25:21