2013-05-15 58 views
10

假設我有一個元組將std元組解壓縮爲指針?

std::tuple<A, B, C> myFavoriteTuple; 

我可以這樣做:

A a; 
B b; 
C c; 
std::tie(a, b, c) = myFavoriteTuple 

但如果一些元組是複製真的很貴,我真正喜歡的是採取或引用一個指向我的元組中正確點的指針。我可以這樣做:

A* a = &std::get<0>(myFavoriteTuple); 
B* b = &std::get<1>(myFavoriteTuple); 
C* c = &std::get<2>(myFavoriteTuple); 

但相比tie語法如何真棒是顯得那麼跛。是否有任何其他方式來獲取指向元組件的指針/引用?

+0

請參閱Boost.Fusion –

+3

在某些情況下,從元組移動可能是最好的想法 - ''''std :: tie(myFavoriteTuple);' – zch

+0

Oh man,C++ 17 is很棒:'auto && [a,b,c] = myFavoriteTuple;'完成。 – Barry

回答

5

由於平時指數基礎設施:

template<int... Is> 
struct seq { }; 

template<int N, int... Is> 
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { }; 

template<int... Is> 
struct gen_seq<0, Is...> : seq<Is...> { }; 

你可以創建一個返回指針的元組的功能,每一個元素是一個指向輸入數組的對應元素:

template<typename... Args, int... Is> 
auto make_pointer_tuple(std::tuple<Args...>& t, seq<Is...>) 
    -> std::tuple<typename std::add_pointer<Args>::type...> 
{ 
    return std::make_tuple(&std::get<Is>(t)...); 
} 

template<typename... Args> 
auto make_pointer_tuple(std::tuple<Args...>& t) 
    -> std::tuple<typename std::add_pointer<Args>::type...> 
{ 
    return make_pointer_tuple(t, gen_seq<sizeof...(Args)>()); 
} 

這就是你如何使用它:

std::tuple<int, bool, std::string> myFavoriteTuple{0, false, ""}; 

int* pInt = nullptr; 
bool* pBool = nullptr; 
std::string* pString = nullptr; 
tie(pInt, pBool, pString) = make_pointer_tuple(myFavoriteTuple); 

這是一個live example

+1

@Barry:是的,通常模板人都在休息室忙着聊天,所以我可以自由地慢慢潛入並回答;) –

+0

想知道這個建議是否會讓它變得更好? http://open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html – balki

+0

@balki:是的,這將標準化指數機制 –

0

以下情況如何?

template<typename T> 
struct ptie 
{ 
    const T *ptr; 
    ptie() 
     :ptr(nullptr) 
    {} 

    void operator=(const T &x) 
    { 
     ptr = &x; 
    } 
}; 

ptie<A> a; 
ptie<B> b; 
ptie<C> c; 
std::tie(a, b, c) = myFavoriteTuple; 

然後您可以使用*a.ptr來訪問該對象。如果你喜歡,你甚至可以覆蓋operator->等。

此方法的主要缺點是由於operator=(const T&),它將元組成員綁定爲const。你可以用ptr = const_cast<T*>(x)刪除它,但我認爲這可能會在某些情況下破壞常量正確性。