参数包扩展顺序 [英] Order of parameter pack expansion

查看:124
本文介绍了参数包扩展顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个函数来读取二进制文件。

I have 2 functions to read binary file.

第一个函数从文件中读取 sizeof(T)个字节:

1st function reads sizeof(T) bytes from file:

template<typename T>
T read() { ... some IO operations ... };

第二个函数使用每个模板参数多次调用第一个:

2nd function calls first one multiple times with each template parameter:

template<typename... Ts>
std::tuple<Ts...> read_all() {
    return std::make_tuple(read<Ts>()...);
};

除第一个函数调用顺序外,一切正常。类似

Everything works fine except of 1st function call order. For something like

uint32_t a;
uint8_t b;
std::tie(a, b) = read_all<uint32_t, uint8_t>();

第一个将被称为 read< uint8_t>()之后读取< uint32>(),它会反转传递模板参数的顺序,并以文件中的字节顺序混乱。

the first will be called read<uint8_t>() and after that read<uint32>() which reverses order of passing template parameters and messes up with order of bytes in file.

当然,我可以用反向的模板参数顺序调用 read_all 并最终得到正确的顺序,但有更明显的方法吗?

Sure, I can call read_all with reversed order of template arguments and get right order in the end, but is there a more obvious way to do so?

推荐答案

C ++没有指定评估函数参数的顺序。如果函数的表达式都使用流中的数据,则可以获得以错误顺序读取对象的行为。

C++ does not specify the order in which a function's arguments are evaluated. If the expressions to a function all consume data from a stream, you can get behavior where objects are read in the wrong order.

从左到右计算支撑的初始化列表但是,如果你尝试这样的话,你应该得到更好的结果:

Braced initializer lists are evaluated from left to right, however, so you should get better results if you try something like:

template<typename... Ts>
std::tuple<Ts...> read_all() {
    return std::tuple<Ts...>{read<Ts>()...};
}

这篇关于参数包扩展顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆