要區分 literal 和 literal-type這兩個不同的概念。
literal:文字量,10,3.14, true ,u8"123", L"好"這些東西。
literal-type: 參考http://en.cppreference.com/w/cpp/concept/LiteralType 簡單的說,就可以在用於編譯期運算的對象。
對於標量,例如int,顯然可以參與編譯期運算,例如:constexpr int fac( int N); //計算階乘。所以標量都是屬於literal-type。
從這里可以看出,literal-type僅僅是類型系統中,一個catalog。所有的類型,要么歸類到literal-type,要么歸類到none-literal-type。
現在class,也能歸類於literal-type,只要滿足一些條件:
1 struct point 2 { 3 point(): x(0), y(0){ std::cout << "point() called" << std::endl; } 4 constexpr point(int x_, int y_): x(x_),y(y_){} 5 constexpr int hypot() { return x*x + y*y; } 6 7 private: 8 int x,y; 9 }; 10 11 int main() 12 { 13 static_assert( point(3,4).hypot() == 25 ); 14 std::cout << "std::is_literal_type<point>::value=" << std::is_literal_type<point>::value; 15 }
point符合literal定義。可以參與到編譯期運算static_assert。下面舉個反例:
1 struct point 2 { 3 point(): x(0), y(0){ std::cout << "point() called" << std::endl; } 4 constexpr point(int x_, int y_): x(x_),y(y_){} 5 constexpr int hypot() { return x*x + y*y; } 6 ~point(){} 7 int x,y; 8 };
第6行,加了析構函數,point就不再是literal-type了。
1 struct point 2 { 3 point(): x(0), y(0){ std::cout << "point() called" << std::endl; } 4 point(int x_, int y_): x(x_),y(y_){} 5 constexpr int hypot() { return x*x + y*y; } 6 private: 7 int x,y; 8 };
第6行,加了private,point就不再是aggregate-type; 並且構造函數去了constexpr。point就不是literal-type.
改造一下:
struct point { point(): x(0), y(0){ std::cout << "point() called" << std::endl; } constexpr point(int x_, int y_): x(x_),y(y_){} constexpr int hypot() { return x*x + y*y; } private: int x,y; };
現在這個none-aggregate-type就是literal-type