我正在尝试实现一个类似元组的类。一切都运转良好。这是我的代码:
元组.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
参数。
您可以通过在
TgetNth
中声明以下内容,使整个 Tuple
模板成为友元:
template<int, typename>
// or template <int N, typename R>, but names are unnecessary
friend struct TgetNth;
请参阅编译器资源管理器中的实时示例。