friend获取返回通过variadic模板递归计算的类型的函数

时间:2016-05-29 13:52:40

标签: c++ c++11 tuples variadic-templates friend

我正在尝试通过带有递归继承和外部get函数的可变参数模板实现std :: tuple。只要元组具有公共继承和公共价值领域,我就能很好地工作。但我需要将它们设为私有并完成它我需要在元组中写一个朋友“get”函数。但问题是返回的“get”类型是通过其他可变参数模板计算的。所以我不知道写什么作为该朋友函数的返回值。

#include <iostream>
#include <type_traits>

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


template <typename T, typename... Ts>
class Tuple<T, Ts...> : public Tuple<Ts...>
{
//    template<size_t k, typename T1, typename... T1s>
//    friend typename tuple_element<k, tuple<T1, T1s...>>::type&
//    get(Tuple<T1, T1s...>& t);
public:
    T m_head;
};

template<size_t index, 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.m_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);
}

int main(int argc, char* argv[])
{
    Tuple<int, int, std::string> t;
    get<2>(t) = "3.14";
    std::cout << get<2>(t) << std::endl;
}

注释代码是我尝试编写此类函数但它不起作用。

1 个答案:

答案 0 :(得分:2)

转发声明tuple_element,然后与两个重载的get函数交朋友:

template <size_t index, typename>
struct tuple_element;

template <typename T, typename... Ts>
class Tuple<T, Ts...> : Tuple<Ts...>
{
    template <size_t k, typename... Us>
    friend typename std::enable_if<k==0, typename tuple_element<0, Tuple<Us...>>::type&>::type get(Tuple<Us...>& t);

    template <size_t k, typename U, typename... Us>
    friend typename std::enable_if<k!=0, typename tuple_element<k, Tuple<U, Us...>>::type&>::type get(Tuple<U, Us...>& t);

private:
    T m_head;
};

DEMO