如何用元组模拟 std::array<15,int &>
How to simulate std::array<15,int &> with tuples
显然std::array<type,count>
不能存储引用。但是可以写
std::tuple<int &, int &, int &, int &, int &>
并得到你期望的。参见
#include <array>
#include <tuple>
#include <iostream>
int main(){
int a = 10;
int b = 20;
int c = 20;
// Does not compile
//std::array<int&,3> x = {a,b,c};
using TInt3 = std::tuple<int&,int&,int&>;
TInt3 y = {a,b,c};
std::cout << sizeof(TInt3) << std::endl;
std::get<0>(y)=11;
std::cout << "a " << a << std::endl;
}
其中a 11
是输出。然而,长手写出来很乏味。如何生成类型(在 c++11 中)
TupleAllSame<type, count>
所以下面是等价的
TupleAllSame<int &, 2> <--> std::tuple<int &, int &>
TupleAllSame<double, 4> <--> std::tuple<double, double, double, double>
TupleAllSame<std::string &, 3> <--> std::tuple<std::string &, std::string &, std::string &>
基于 C++11 implementation of std::index_sequence
(我将其塞入 std14
命名空间):
namespace impl {
template <class T, class Idx>
struct TupleAllSame;
template <class T, std::size_t... Idx>
struct TupleAllSame<T, std14::index_sequence<Idx...>> {
template <class U, std::size_t>
using depend = U;
using type = std::tuple<depend<T, Idx>...>;
};
}
template <class T, std::size_t Size>
using TupleAllSame = typename impl::TupleAllSame<T, typename std14::make_index_sequence<Size>::type>::type;
std::reference_wrapper
可以用作数组的元素。语法有时会有点复杂,但它有效:
#include <functional>
#include <array>
#include <iostream>
int main(){
int a = 10;
int b = 20;
int c = 20;
using rint = std::reference_wrapper<int>;
std::array<rint,3> x = {a,b,c};
std::cout << "a " << a << std::endl;
x[0].get()=11;
std::cout << "a " << a << std::endl;
}
没有index_sequence的解决方案基于递归 (Wandbox Live)
#include<iostream>
#include <tuple>
using namespace std;
template <int N, typename T, typename SeqWithArgs>
struct append;
template <int N, typename T, template <typename...> class Seq, typename... Args >
struct append<N, T, Seq<Args...> >
{
using type = typename append<N - 1, T, Seq<T, Args...> >::type;
};
template <typename T, template<typename...> class Seq, typename... Args>
struct append<0, T, Seq<Args...> >
{
using type = Seq<Args...>;
};
template <typename T, size_t Size>
using TupleAllSame = typename append<Size, T, std::tuple<> >::type;
int main()
{
int a = 0, b = 1, c = 2;
TupleAllSame<int&, 3> t = { a,b, c };
get<0>(t) = 10;
cout << "a = " << a << endl;
return 0;
}
显然std::array<type,count>
不能存储引用。但是可以写
std::tuple<int &, int &, int &, int &, int &>
并得到你期望的。参见
#include <array>
#include <tuple>
#include <iostream>
int main(){
int a = 10;
int b = 20;
int c = 20;
// Does not compile
//std::array<int&,3> x = {a,b,c};
using TInt3 = std::tuple<int&,int&,int&>;
TInt3 y = {a,b,c};
std::cout << sizeof(TInt3) << std::endl;
std::get<0>(y)=11;
std::cout << "a " << a << std::endl;
}
其中a 11
是输出。然而,长手写出来很乏味。如何生成类型(在 c++11 中)
TupleAllSame<type, count>
所以下面是等价的
TupleAllSame<int &, 2> <--> std::tuple<int &, int &>
TupleAllSame<double, 4> <--> std::tuple<double, double, double, double>
TupleAllSame<std::string &, 3> <--> std::tuple<std::string &, std::string &, std::string &>
基于 C++11 implementation of std::index_sequence
(我将其塞入 std14
命名空间):
namespace impl {
template <class T, class Idx>
struct TupleAllSame;
template <class T, std::size_t... Idx>
struct TupleAllSame<T, std14::index_sequence<Idx...>> {
template <class U, std::size_t>
using depend = U;
using type = std::tuple<depend<T, Idx>...>;
};
}
template <class T, std::size_t Size>
using TupleAllSame = typename impl::TupleAllSame<T, typename std14::make_index_sequence<Size>::type>::type;
std::reference_wrapper
可以用作数组的元素。语法有时会有点复杂,但它有效:
#include <functional>
#include <array>
#include <iostream>
int main(){
int a = 10;
int b = 20;
int c = 20;
using rint = std::reference_wrapper<int>;
std::array<rint,3> x = {a,b,c};
std::cout << "a " << a << std::endl;
x[0].get()=11;
std::cout << "a " << a << std::endl;
}
没有index_sequence的解决方案基于递归 (Wandbox Live)
#include<iostream>
#include <tuple>
using namespace std;
template <int N, typename T, typename SeqWithArgs>
struct append;
template <int N, typename T, template <typename...> class Seq, typename... Args >
struct append<N, T, Seq<Args...> >
{
using type = typename append<N - 1, T, Seq<T, Args...> >::type;
};
template <typename T, template<typename...> class Seq, typename... Args>
struct append<0, T, Seq<Args...> >
{
using type = Seq<Args...>;
};
template <typename T, size_t Size>
using TupleAllSame = typename append<Size, T, std::tuple<> >::type;
int main()
{
int a = 0, b = 1, c = 2;
TupleAllSame<int&, 3> t = { a,b, c };
get<0>(t) = 10;
cout << "a = " << a << endl;
return 0;
}