2013-05-15 54 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)删除它,但我认为这可能会在某些情况下破坏常量正确性。