[英]Variadic template array invokes undefined behavior
我正在嘗試提供一個參數包來初始化一個數組。 我認為它應該起作用,因為:
sizeof...
來獲取參數包的大小sizeof
是一個編譯時構造,所以在編譯時應該知道它,這意味着arr
不應該是一個變長數組然而,我得到了垃圾作為輸出和警告。 先上代碼:
#include <iostream>
#include <utility>
template <typename... Args>
void foo(Args&&... args)
{
int arr[sizeof...(Args)]{std::forward<Args>(args)()...};
for (auto i = 0u; i < sizeof(arr); ++i)
std::cout << arr[i];
}
int a() { return 1; }
int b() { return 2; }
int c() { return 3; }
int main()
{
foo(a, b, c);
}
然后是警告和輸出:
warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]
std::cout << arr[i];
~~~~~~~~~~^~~~~~~
note: within this loop
for (auto i = 0u; i < sizeof(arr); ++i)
~~^~~~~~~~~
1230-282327744327670000-133971368332712
誰能看到我的錯誤?
template <typename... Args>
void foo(Args&&... args)
{
// edit 1 : define the extent of the array once, reuse.
constexpr std::size_t extent = sizeof...(Args);
// edit 2 : in this case, no need to forward references since
// we're not actually forwarding them anywhere
int arr[extent]{args()...};
// edit 3 : 0 < i < extent of array
for (std::size_t i = 0; i < extent ; ++i)
std::cout << arr[i];
}
正如@Casey 在評論中提到的, sizeof(arr)
返回您為數組選擇的類型的變量的大小乘以數組本身的長度(在您的情況下, 3 * sizeof(int)
)。
要解決它,您可以使用以下方法迭代sizeof...(Args)
:
for (auto i = 0u; i < sizeof...(Args); ++i)
或者在填充數組時打印值,如下所示:
#include <iostream>
#include <utility>
template <typename... Args>
void foo(Args&&... args) {
int arr[sizeof...(Args)] = {
(std::cout << args(), std::forward<Args>(args)())...
};
(void)arr;
}
int a() { return 1; }
int b() { return 2; }
int c() { return 3; }
int main() {
foo(a, b, c);
}
如果該函數的唯一目的是打印值,您還可以使用以下命令:
int arr[sizeof...(Args)] = { (std::cout << args(), 0)... };
請注意,上面的代碼沒有考慮sizeof...(Args)
等於0
。
這樣做確實很簡單,我已經把它排除在了答案之外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.