2013-08-18 44 views
9

Tôi vừa hỏi hai câu hỏi về khởi tạo mảng và giá trị herehere. Nhưng với mã này, tôi mất:Tại sao std :: mảng <int, 10> x không phải là 0 được khởi tạo nhưng std :: mảng <int, 10> x = std :: mảng <int, 10>() có vẻ là?

#include <iostream> 
#include <iomanip> 
#include <array> 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f1(const unsigned int i) 
{T x; return x.at(i);} 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f2(const unsigned int i) 
{T x = T(); return x.at(i);} 

int main() 
{ 
    static const unsigned int n = 10; 
    static const unsigned int w = 20; 
    for (unsigned int i = 0; i < n; ++i) { 
     std::cout<<std::setw(w)<<i; 
     std::cout<<std::setw(w)<<f1<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<f2<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<std::endl; 
    } 
    return 0; 
} 

Đúng như dự đoán, f1 trở về giá trị độc đoán như giá trị của nó không phải là zero-khởi tạo. Nhưng f2 dường như trở lại độc quyền không giá trị:

    0     0     0 
        1     61     0 
        2     0     0 
        3     0     0 
        4   297887440     0 
        5    32767     0 
        6    4196848     0 
        7     0     0 
        8   297887664     0 
        9    32767     0 

Cá nhân tôi nghĩ rằng f2 sẽ tạo ra một mảng với giá trị tùy ý và sao chép/di chuyển nó đến x. Nhưng nó không có vẻ như vậy.

Vì vậy, tôi có hai câu hỏi:

  • Tại sao?
  • Do C++ 11 std::array<T, N> và C-style T[N] có cùng hành vi trong trường hợp như vậy?
+3

'T()' là giá trị được khởi tạo 'T'. Và cú pháp không hợp lệ nếu 'T' là kiểu mảng kiểu C. 'T x = {};' hoặc 'T x {};' là các cú pháp áp dụng chung hơn. – Casey

+0

@Giá trị giá trị giá trị cao áp dụng cho các mảng kiểu C. 'T()' là một lỗi cú pháp nếu 'T' không phải là một kiểu định danh kiểu đơn giản, tức là một từ định danh duy nhất hoặc một từ khóa có tên là một kiểu. Trong C++ 03, '= {}' chỉ áp dụng cho các mảng và '{}' đơn giản là một lỗi. – Potatoswatter

+0

Bản sao được cho là về khởi tạo giá trị nhưng câu hỏi này là về khởi tạo mặc định. Vui lòng mở lại và tìm một bản sao phù hợp hoặc chỉ trả lời. – Potatoswatter

Trả lời

9

Sử dụng {} hoặc () làm bộ khởi tạo, với số không có =, dẫn đến khởi tạo giá trị. Đối với một kiểu với một hàm tạo ngầm được khai báo ngầm định, khởi tạo giá trị thực hiện khởi tạo không, như tên của nó đề xuất đặt mỗi phần tử nguyên thủy là 0. Điều này xảy ra trước khi hàm tạo có thể chạy, nhưng trong trường hợp này, hàm tạo không làm gì cả.

Vì hàm tạo không làm gì cả (nó là tầm thường), có thể thấy dữ liệu chưa được khởi tạo.

Đối với mảng kiểu C, hành vi tương tự nếu bạn sử dụng = {} thay vì = T(), vì sau này là bất hợp pháp. T() sẽ yêu cầu đối tượng mảng tạm thời được gán cho đối tượng được đặt tên, nhưng không thể chỉ định mảng. Mặt khác, = {} gán một danh sách-initializer-braced vào mảng, và một danh sách khởi tạo-braced là một cấu trúc cú pháp đặc biệt không phải là một biểu thức hay một đối tượng.