c++ - 可变参数模板和 Alexandrescu 元组实现

标签 c++ variadic-templates

我试着学习一点关于模板元编程和 目前我在玩可变参数模板。

在他的演讲“Variadic Templates are Funadic”中,Alexandrescu 介绍了一个 小元组实现,我尝试构建并可能扩展一个 一点。 (我知道这是一个玩具示例,我只是尝试学习一点 关于 c++ 的更多信息)。但是,我对他的代码有一个小问题。

这里是:

template <typename... Ts> 
class tuple
{};

template<size_t, typename> struct tuple_element;

template<typename T, typename... Ts>
struct tuple_element<0, tuple<T, Ts...>> 
{
    typedef T type;
};

template <size_t k, typename T, typename... Ts>
struct tuple_element<k, tuple<T, Ts...>> 
{
    typedef 
       typename tuple_element<k-1,tuple<Ts...>>::type type;
};

template<size_t k, typename... Ts>
typename std::enable_if<k == 0, 
                        typename tuple_element<0,tuple<Ts...>>::type&>::type
   get(tuple<Ts...>& t)
{return t.head_;}

template<size_t k, typename T, typename... Ts>
typename std::enable_if<k != 0,
                        typename tuple_element<k,tuple<T,Ts...>>::type&>::type
   get(tuple<T,Ts...>& t)
{
    tuple<Ts...> & super = t;
    return get<k-1>(super);
}

template <typename T, typename... Ts>
class tuple<T,Ts...> : private tuple<Ts...> 
{
private:
   T head_;

};

int main(int argc, char *argv[])
{   
     tuple<int,std::string> t;
     get<0>(t) = 10;
     get<1>(t) = std::string("test");
     std::cout<<get<0>(t)<<std::endl;
}

为了正确工作,get 函数必须是 元组类(本幻灯片中也提到了它,请参见第 32 页)。但是如何 friend 声明看起来像吗?我尝试了不同的方法 但无法让它工作。当我将代码从私有(private)继承更改为公共(public)继承时 并将 head_ 的访问规则更改为 public 它有效。

谢谢你的帮助

凯文

最佳答案

这对我有用:

template <typename T, typename... Ts>
class tuple<T,Ts...> : private tuple<Ts...> 
{
private:
   T head_;

   template<size_t k, typename T1, typename... T1s>
   friend typename std::enable_if<k != 0,
                        typename tuple_element<k,tuple<T1,T1s...>>::type&>::type
   get(tuple<T1,T1s...>& t);

   template<size_t k, typename... T1s>
   friend typename std::enable_if<k == 0, 
                        typename tuple_element<0,tuple<T1s...>>::type&>::type
   get(tuple<T1s...>& t);

};

Demo .

关于c++ - 可变参数模板和 Alexandrescu 元组实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25824032/

相关文章:

c++ - 如何使用 boost::asio 即时更改串行端口速度(或如何确定硬件缓冲区是否为空)?

python - 如何使用 CFFI 将多维 Numpy 数组传递给 C 函数?

c++ - 如何决定是否使用超线程?

c++ - 根据参数数量调用mixin基类的构造方法

c++ - 具有方法重载的接口(interface)类?

c++ - 在堆上初始化的指针数据成员

c++ - 我如何检查这是否是 std::list 的最后一个成员?

c++ - 用于转换多个参数的模板函数

c++ - 如何扩展基类的参数包并调用每个基类的成员函数?

C++20 如何获取 std::size_t 参数包的最后一个元素