2016-05-29 6 views
-5

配列を初期化するためのパラメータパックを提供しようとしています。私はそれはテンプレートだ、とsizeofは、コンパイル時の構造なので、それは、コンパイル時に知られているべきパラメータパック Variadicテンプレート配列が未定義の動作を呼び出す

  • のサイズを取得するために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 
    

    誰もが私の間違いを見ることができますか?

    @Caseyによるコメントで述べたように
  • +9

    'sizeof(arr)== sizeof ...(Args)* sizeof(int)'です。代わりに 'i Casey

    +4

    'sizeof'はサイズをバイト単位で返します。 – milleniumbug

    答えて

    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]; 
    } 
    
    0

    は、sizeof(arr)3 * sizeof(int)、あなたのケースで)あなたは、配列のために選択したタイプの変数のサイズは、配列自体の長さのために掛け返します。の唯一の目的ならば

    #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); 
    } 
    

    for (auto i = 0u; i < sizeof...(Args); ++i) 
    

    それとも、それは次のように、配列を埋めながら値を出力:それを解決するために

    、あなたはこれを使用してsizeof...(Args)を反復処理しますか関数は、値を印刷することです、あなたもこれを使用することができます:

    int arr[sizeof...(Args)] = { (std::cout << args(), 0)... }; 
    

    上記のeコードでは、sizeof...(Args)のケースは0とはみなされません。
    それは本当にそれを行うことは非常に自明で、私は答えからそれを残した。

    関連する問題