C++ 可变模板包扩展参数id

C++ 可变模板包扩展参数id,c++,c++11,variadic-templates,C++,C++11,Variadic Templates,我正在尝试创建一个可变模板函数,该函数按顺序读取元素(带有索引)。例如,目标是调用函数read_tuple来读取id为0和1的两个整数(read_int(0)和read_int(1)) 以下是我目前得到的代码: int data[] = {10,20,30,40}; int int_read(int id) { return data[id]; } template <typename T> T read(int& index) { index--;

我正在尝试创建一个可变模板函数,该函数按顺序读取元素(带有索引)。例如,目标是调用函数read_tuple来读取id为0和1的两个整数(read_int(0)和read_int(1))

以下是我目前得到的代码:

int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int& index)
{
    index--;
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    int index = sizeof...(Args);
    return std::tuple<Args...>(read<Args>(index)...);
}

但是,此代码取决于读取函数的计算顺序。如何生成依赖于包扩展的索引(以避免未定义的行为)?

正如Piotr所指出的,如果使用带括号的init list,则可以保证计算顺序。但是,如果在4.9.1之前使用GCC,请小心,因为它不起作用(c.f.)

如果您使用的版本不保证初始化顺序(或只想生成ID),则可以使用索引器(从):

模板结构索引{
使用append=index的模板;
};
模板结构生成索引{
typedef typename make_index::type::template append type;
};
模板结构使_索引{typedef index type;};
使用indexer=typename make_index::type的模板;
您可以这样使用它:

auto tuple = read_tuple<int, int>();
std::cout << "First: " << std::get<0>(tuple) << std::endl;
int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int index)
{
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args, int... i>
std::tuple<Args...> read_tuple_indexed(index<i...>)
{
    return std::tuple<Args...>(read<Args>(i)...);
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    return read_tuple_indexed<Args...>(indexer<(sizeof...(Args))>());
}
int data[]={10,20,30,40};
整数读取(整数id)
{
返回数据[id];
}
模板
T读取(整数索引)
{
int值=int_读取(索引);

std::cout正如Piotr所指出的,如果您使用带括号的init list,则评估顺序是有保证的。但是,如果您在4.9.1之前使用GCC,则要小心,因为它不起作用(c.f.)

如果您使用的版本不保证初始化顺序(或只想生成ID),则可以使用索引器(从):

模板结构索引{
使用append=index的模板;
};
模板结构生成索引{
typedef typename make_index::type::template append type;
};
模板结构使_索引{typedef index type;};
使用indexer=typename make_index::type的模板;
您可以这样使用它:

auto tuple = read_tuple<int, int>();
std::cout << "First: " << std::get<0>(tuple) << std::endl;
int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int index)
{
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args, int... i>
std::tuple<Args...> read_tuple_indexed(index<i...>)
{
    return std::tuple<Args...>(read<Args>(i)...);
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    return read_tuple_indexed<Args...>(indexer<(sizeof...(Args))>());
}
int data[]={10,20,30,40};
整数读取(整数id)
{
返回数据[id];
}
模板
T读取(整数索引)
{
int值=int_读取(索引);

std::cout正如Piotr所指出的,如果您使用带括号的init list,则评估顺序是有保证的。但是,如果您在4.9.1之前使用GCC,则要小心,因为它不起作用(c.f.)

如果您使用的版本不保证初始化顺序(或只想生成ID),则可以使用索引器(从):

模板结构索引{
使用append=index的模板;
};
模板结构生成索引{
typedef typename make_index::type::template append type;
};
模板结构使_索引{typedef index type;};
使用indexer=typename make_index::type的模板;
您可以这样使用它:

auto tuple = read_tuple<int, int>();
std::cout << "First: " << std::get<0>(tuple) << std::endl;
int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int index)
{
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args, int... i>
std::tuple<Args...> read_tuple_indexed(index<i...>)
{
    return std::tuple<Args...>(read<Args>(i)...);
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    return read_tuple_indexed<Args...>(indexer<(sizeof...(Args))>());
}
int data[]={10,20,30,40};
整数读取(整数id)
{
返回数据[id];
}
模板
T读取(整数索引)
{
int值=int_读取(索引);

std::cout正如Piotr所指出的,如果您使用带括号的init list,则评估顺序是有保证的。但是,如果您在4.9.1之前使用GCC,则要小心,因为它不起作用(c.f.)

如果您使用的版本不保证初始化顺序(或只想生成ID),则可以使用索引器(从):

模板结构索引{
使用append=index的模板;
};
模板结构生成索引{
typedef typename make_index::type::template append type;
};
模板结构使_索引{typedef index type;};
使用indexer=typename make_index::type的模板;
您可以这样使用它:

auto tuple = read_tuple<int, int>();
std::cout << "First: " << std::get<0>(tuple) << std::endl;
int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int index)
{
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args, int... i>
std::tuple<Args...> read_tuple_indexed(index<i...>)
{
    return std::tuple<Args...>(read<Args>(i)...);
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    return read_tuple_indexed<Args...>(indexer<(sizeof...(Args))>());
}
int data[]={10,20,30,40};
整数读取(整数id)
{
返回数据[id];
}
模板
T读取(整数索引)
{
int值=int_读取(索引);

std::cout通过使用带括号的init list
std::tuple{read(index)…}
可以保证按外观顺序(即从左到右)执行,通过使用带括号的init list
std::tuple{read(index)…}
可以保证按外观顺序(即从左到右)执行通过使用带括号的init list
std::tuple{read(index)…}
可以保证按照外观顺序(即从左到右)执行,通过使用带括号的init list
std::tuple{read(index)…}
可以保证按照外观顺序(即从左到右)执行