2012-05-10 49 views
7

Tôi tự hỏi nếu có thể khởi tạo toàn bộ mảng với hàm constexpr (với C++ 2011). Ở đây tôi có một cái gì đó để minh họa cho những gì tôi muốn làm:Khởi tạo một mảng với một constexpr?

template<unsigned int DIM> const unsigned int MyClass<DIM>::_myVar[2][3] = { 
{metaFunction(0, 0, DIM), metaFunction(0, 1, DIM), metaFunction(0, 2, DIM)}, 
{metaFunction(1, 0, DIM), metaFunction(1, 1, DIM), metaFunction(1, 2, DIM)} 
}; 

template<unsigned int DIM> inline constexpr unsigned int MyClass<DIM>::metaFunction(const unsigned int k, const unsigned int n, const unsigned int dim) 
{ 
    return (((n < dim) && (k < n)) ? (1<<(n-k)) : (0)); 
} 

Có cách nào để khởi tạo myVar với một constexpr mà không làm đầy mảng bằng tay. Và nếu nó tồn tại, cú pháp của ví dụ đã cho là gì?

Để đặt câu hỏi một cách chính xác một chút, tôi tìm cách điền vào tất cả các giá trị của myVar bằng một cuộc gọi chức năng duy nhất.

+0

Làm thế nào về một danh sách initializer: (http://stackoverflow.com/questions/907471/c0x-initializer-list-example) – fileoffset

+2

Bạn có ý nghĩa gì bởi "không điền mảng bằng tay"? Ngoài ra, bạn không cần một 'constexpr' ở đây. Bạn sẽ nếu bạn đã thiết lập kích thước của '_myVar'. – juanchopanza

+0

@juanchopanza: Tôi nghĩ câu hỏi là: Làm thế nào để lấp đầy một mảng constexpr bằng cách sử dụng các hàm constexpr theo cách tổng quát? – mirk

Trả lời

3

Không nhìn thấy định nghĩa MyClass vấn đề không rõ ràng. Tôi tin rằng dù sao bạn muốn nhận được MyClass::_myVar được khởi tạo mà không cần mã để lặp lại nó với giá trị MyClass::metaFunction().

Mã bạn đề xuất rằng MyClass::_myVar là thành viên lớp tĩnh. Trong trường hợp đó trường hợp khởi tạo thành viên của bạn là hoàn toàn tốt C++ 11 như nó đứng. Chương trình sau minh họa (GCC 4.6.3):

#include <iostream> 

/* MyClass Version 1 */ 
template<unsigned int DIM> 
struct MyClass 
{ 
    static constexpr unsigned int metaFunction(
     const unsigned int k, 
     const unsigned int n, 
     const unsigned int dim); 

    static const unsigned int _myVar[2][3]; 
}; 

template<unsigned int DIM> inline constexpr 
unsigned int MyClass<DIM>::metaFunction(
    const unsigned int k, 
    const unsigned int n, 
    const unsigned int dim) 
{ 
    return (((n < dim) && (k < n)) ? (1<<(n-k)) : (0)); 
} 

template<unsigned int DIM> const unsigned int MyClass<DIM>::_myVar[2][3] = { 
    { metaFunction(0, 0, DIM), 
     metaFunction(0, 1, DIM), 
     metaFunction(0, 2, DIM) 
    }, 
    { metaFunction(1, 0, DIM), 
     metaFunction(1, 1, DIM), 
     metaFunction(1, 2, DIM) 
    } 
}; 

template<unsigned int DIM> inline constexpr 
unsigned int MyClass<DIM>::metaFunction(
    const unsigned int k, 
    const unsigned int n, 
    const unsigned int dim) 
{ 
    return (((n < dim) && (k < n)) ? (1<<(n-k)) : (0)); 
} 

using namespace std; 

int main(void) 
{ 
    MyClass<3> mine; 
    for (int i = 0; i < 2; ++i) { 
     for (int j = 0; j < 3; ++j) { 
      cout << mine._myVar[i][j] << endl; 
     } 
    } 
    return 0; 
} 

này nghiêng tôi nghĩ rằng MyClass::_myVarkhông thành viên tĩnh - mặc dù lý do tại sao mảng này của hằng số nguyên sẽ không được tĩnh Tôi không chắc chắn . Nếu đó là trường hợp, sau đó bạn có thể khởi tạo các thành viên trong constructor mặc định sử dụng uniform initialization provision of C++11:

/* MyClass Version 2 */ 
template<unsigned int DIM> 
struct MyClass 
{ 
    MyClass() 
    : _myVar{ 
      { MyClass::metaFunction(0, 0, DIM), 
       MyClass::metaFunction(0, 1, DIM), 
       MyClass::metaFunction(0, 2, DIM) 
      }, 
      { MyClass::metaFunction(1, 0, DIM), 
       MyClass::metaFunction(1, 1, DIM), 
       MyClass::metaFunction(1, 2, DIM) 
      } 
    }{} 

    static constexpr unsigned int metaFunction(
     const unsigned int k, 
     const unsigned int n, 
     const unsigned int dim); 

    const unsigned int _myVar[2][3]; 
}; 

Trong trường hợp không phải là thuộc tính của constexprmetaFunction thực cần thiết để biên dịch. Và nếu constexpr bị xóa thì /* MyClass Version 1*/ cũng tốt cho C++ 03.

Các vấn đề liên quan