2016-06-29 31 views
8

Tôi đang cố gắng tìm hiểu thêm một chút về cách sử dụng C++ biểu thức liên tục trong thực tế và tạo ra các mẫu sau lớp Matrix cho mục đích minh hoạ:Tại sao trình biên dịch phàn nàn về điều này không phải là một constexpr?

#include <array> 

template <typename T, int numrows, int numcols> 
class Matrix{ 
public: 
    using value_type = T; 
    constexpr Matrix() : {} 
    ~Matrix(){} 

    constexpr Matrix(const std::array<T, numrows*numcols>& a) : 
     values_(a){} 

    constexpr Matrix(const Matrix& other) : 
     values_(other.values_){ 

    } 

    constexpr const T& operator()(int row, int col) const { 
     return values_[row*numcols+col]; 
    } 

    T& operator()(int row, int col){ 
     return values_[row*numcols+col]; 
    } 

    constexpr int rows() const { 
     return numrows; 
    } 

    constexpr int columns() const { 
     return numcols; 
    } 


private: 
    std::array<T, numrows*numcols> values_{}; 
}; 

Ý tưởng là để có một lớp Matrix đơn giản, mà tôi có thể sử dụng cho các ma trận nhỏ để đánh giá biểu thức ma trận tại thời gian biên dịch (lưu ý rằng tôi chưa triển khai các toán tử Matrix thông thường để bổ sung và nhân).

Khi tôi cố gắng để khởi tạo một trường hợp Matrix như sau:

constexpr std::array<double, 4> a = {1,1,1,1}; 
constexpr Matrix<double, 2, 2> m(a); 

Tôi nhận được lỗi sau từ trình biên dịch (MS Visual C++ 14):

error: C2127: 'm': illegal initialization of 'constexpr' entity with a non-constant expression 

Note chắc chắn những gì tôi làm sai ... bất kỳ trợ giúp nào để thực hiện công việc này sẽ được đánh giá cao!

+0

lẽ 'std :: array' không có một constructor sao chép constexpr? –

+2

Xóa định nghĩa của hàm hủy –

+2

Là một sidenote, không cần lưu trữ 'numrows_' và' numcols_' làm biến thành viên. Vì bạn đã có các giá trị như các tham số mẫu, chỉ cần trả về các giá trị đó. –

Trả lời

13

[basic.types]/p10 khẳng định rằng:

Một loại là một đen loại nếu nó là:

  • thể cv-trình độ void; hoặc

  • loại vô hướng; hoặc

  • loại tham chiếu; hoặc

  • một mảng kiểu chữ; hoặc

  • một loại có thể cv-trình độ lớp (khoản [class]) mà có tất cả các thuộc tính sau:

    • nó có một destructor tầm thường,

    • nó là một trong hai loại đóng cửa ([expr.prim.lambda]), loại tổng hợp ([dcl.init.aggr]) hoặc có ít nhất một hàm tạo hoặc mẫu hàm tạo (có thể được kế thừa ([namespace.udecl]) từ một lớp cơ sở) không phải là một bản sao hoặc di chuyển,

    • nếu nó là một sự kết hợp, ít nhất một trong các thành viên dữ liệu không tĩnh của nó là loại văn chương không dễ bay hơi, và

    • nếu nó không phải là một liên minh, tất cả của nó các thành viên dữ liệu tĩnh không và cơ sở các lớp là các kiểu chữ không bay hơi.

nơi [class.dtor]/p5 nói rằng:

Một destructor là tầm thường nếu nó không phải là người dùng cung cấp và nếu:

(5.4) - destructor không phải là virtual,

(5,5) - tất cả các lớp cơ sở trực tiếp của các lớp học đã destructors tầm thường, và

(5,6) - cho tất cả các phi các thành viên dữ liệu tĩnh của lớp của nó thuộc loại lớp (hoặc mảng của chúng), mỗi lớp như vậy có một hàm hủy nhỏ.

Nếu không, trình phá hủy là không tầm thường.

Nói cách khác, để khai báo một trường hợp constexpr của Matrix, nó phải là một kiểu chữ, và trở thành một loại đen, destructor của nó phải là default ed, hoặc gỡ bỏ hoàn toàn, vì vậy:

~Matrix() = default; 

hay:


                
+0

Cảm ơn rất nhiều về tất cả các giải thích! – BigONotation

+6

Tôi thích _or_. :-) – skypjack

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