如何将类模板声明为其他模板类的友元

问题描述 投票:0回答:1

我正在尝试实现一个类似元组的类。一切都运转良好。这是我的代码:

元组.hpp

#pragma once

template<typename Head, typename... Tail>
class Tuple : private Tuple<Tail...>
{
   using Base = Tuple<Tail...>;

public:
   Tuple(Head head, Tail... tail) : Base{ tail... }, m_head{ head }{};
   Head& GetHead()
   {
    return m_head;
   }

    Base* base()
    {
        return static_cast<Base*>(this);
    }
    
    const Base* base() const
    {
        return static_cast<const Base*>(this);
    }

private:
    Head m_head;
};

template<typename Head>
class Tuple<Head>
{
public:
    Tuple(Head head) : m_head{ head } {};

    Head& GetHead()
    {
        return m_head;
    }

private:
    Head m_head;
};

template<int N, typename... Tail>
struct select;

template<int N, typename Head, typename... Tail>
struct select<N, Head, Tail...> : select<N - 1, Tail...>
{};

template<typename Head, typename... Tail>
struct select<0, Head, Tail...>
{
    using type = Head;
};

template<int N, typename... Tail>
using Select = typename select<N, Tail...>::type;

template<int N, typename R>
struct TgetNth
{
    template<typename T>
    static R& get(T& t)
    {
        return TgetNth<N - 1, R>::get(*t.base());
    }
};

template<typename R>
struct TgetNth<0, R>
{
    template<typename T>
    static R& get(T& t)
    {
        return t.GetHead();
    }
};

template<int N, typename... Tail>
Select<N, Tail...> get(Tuple<Tail...>& t)
{
    return TgetNth<N, Select<N, Tail...>>::get(t);
}

主.cpp

#include <iostream>
#include "Tuple.hpp"

int main()
{
    Tuple<double, int, std::string, double> tup{ 1.1, 10, "Hello world", 2.2 };

    std::cout << get<0>(tup) << std::endl;
    std::cout << get<1>(tup) << std::endl;
    std::cout << get<2>(tup) << std::endl;
    std::cout << get<3>(tup) << std::endl;
    
    return 0;
}

如您所见,

struct TgetNth
使用公共方法
Head& Tuple::GetHead()
Base* Tuple::base()
。我的想法是将这些方法设为私有,并将
struct TgetNth
声明为
Tuple
的朋友。我试着把它做成这样:

friend struct TgetNth<0, Select<0, Tail...>>;

但是我从编译器中得到一个错误:

错误C2248:'Tuple::m_head':无法访问类'Tuple'中声明的私有成员

我会说实话。我不知道如何去做。障碍是模板的

int N
参数。

c++ class templates friend
1个回答
1
投票

您可以通过在

TgetNth
中声明以下内容,使整个
Tuple
模板成为友元:

template<int, typename>
// or template <int N, typename R>, but names are unnecessary
friend struct TgetNth;

请参阅编译器资源管理器中的实时示例

© www.soinside.com 2019 - 2024. All rights reserved.