2016-05-29 3 views
1

私は、再帰的継承と外部取得関数を持つvariadicテンプレートを通してstd :: tupleを実装しようとしています。タプルが公開継承と公的価値の分野を持っている限り、私はうまくいきます。しかし、私はそれらをプライベートにする必要があり、それを達成するためには、タプルに友人の "get"関数を書く必要があります。しかし、問題は、返された型の "get"は他のバリデーショナルなテンプレートを通して計算されるということです。だから私はその友人の関数の戻り値として何を書くべきか分からない。variadicテンプレートを使って再帰的に計算するタイプを返すfriend 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; 
} 

コメントコードは、このような関数を記述する私の試みだったが、それは動作しません。

答えて

2

tuple_elementフォワード-宣言し、その後2つのオーバーロードされた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

+0

はありがとうございます。プライベートなm_headで動作します。私的継承も可能ですか? – OmegaDoom

+0

@OmegaDoomは、2番目のオーバーロードを友達にもします。 –

+0

@OmegaDoom http://coliru.stacked-crooked.com/a/7de9ed538131e47e –

関連する問題