std::tuple()那么今天我在使用and時遇到了一個奇怪的行為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, 4和2, 1, 3, 4. 這出乎我的意料。我求助于我的朋友,得到了“宏rd是一個不確定的行為”的回復。但是,在了解了一些關于unspecific behaivor的知識后,我仍然對這個答案感到困惑。
uj5u.com熱心網友回復:
你的朋友是對的。
未指定的行為發生是因為未指定函式引數的評估順序,它可以以任何順序發生并且可以在呼叫之間更改。std::cin這意味著不能保證的順序。編譯器可以自由地對它們重新排序,因為它認為合適。這適用于std::tuple(),因此輸出不正確。
另一方面,對于braced-init-list,順序是從左到右固定的,因此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>()...};
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/517232.html
標籤:C
上一篇:typeid(*this).name()在std::exception子類的委托建構式上回傳空指標
下一篇:c 中字串的擦除功能
