我正在尝试提供参数包来初始化数组。我认为它应该有效,因为:
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
任何人都可以看到我的错误吗?
答案 0 :(得分:0)
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];
}
答案 1 :(得分:0)
正如@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
的情况
这样做确实非常微不足道,我将其排除在答案之外。