簡體   English   中英

可變模板數組調用未定義的行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM