gpt4 book ai didi

c++ - std::tuple 中的括号和大括号有什么区别?

转载 作者:行者123 更新时间:2023-12-02 18:02:13 25 4
gpt4 key购买 nike

今天,我在使用 std::tuple()std::tuple{} 时遇到了奇怪的行为。

这是一个简单的演示:

#include <iostream>
#include <tuple>

#define rd ({ int x = (std::cin >> x, x); x; })

template <typename... Args>
void log(const Args &...args) { ((::std::cout << args << ", "), ...); }

auto main() -> int {

auto [a, b] = std::tuple(rd, rd);
auto [c, d] = std::tuple{rd, rd};

log(a, b, c, d);

return {};
}

运行:

 echo '1 2 3 4' > input
clang++ -std=c++17 demon.cpp
./a.out < input
g++ -std=c++17 demon.cpp
./a.out < input
cat demon.cpp

我得到了 2 个不同的结果:1, 2, 3, 42, 1, 3, 4。这出乎我的意料。我向 friend 求助,得到的回复是“宏rd是一种非特定行为”。然而,在了解了一些关于非特定行为的知识后,我仍然对这个答案感到困惑。

最佳答案

你的 friend 是正确的。

发生未指定的行为是因为未指定函数参数的求值顺序,它可以按任何顺序发生,并且可以在调用之间发生变化。含义为 std::cin 的顺序不保证。编译器可以根据需要自由地对它们重新排序。这适用于std::tuple() ,因此输出不正确。

另一方面,对于花括号初始化列表,顺序是从左到右固定的,因此 std::tuple{}安全,输出有保障。

此外,在rd中,在表达式中使用大括号语句不是标准 C++,因此您将受到编译器的支配。我会认真推荐无宏重构,隐藏 std::cin表情里好像是自找麻烦。

为什么不简单read_int()函数或通用read_T ?然后你可以推广到 read_Ts<T1,T2,T3...>具有明确的排序。例如:

template<typename T>
T read_T(){
T x;
std::cin>> x;
return x;
}

template<typename...T>
auto read_Ts(){
return std::tuple{read_T<T>()...};
}

关于c++ - std::tuple 中的括号和大括号有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74106522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com