2012-02-07 10 views
7

Tại sao tính năng này hoạt động?const biến là tham số mẫu không phải kiểu (VARIABLE không thể xuất hiện trong biểu thức không đổi)

char __nontype[] = "foo"; 
typedef TemplateClass<T, __nontype> MyClass; 

Nhưng điều này (có biến cố định) phải không?

const char __nontype[] = "foo"; 
typedef TemplateClass<T, __nontype> MyClass; 

Lỗi trình biên dịch:

lỗi: '__nontype' không thể xuất hiện trong một hằng số thể hiện

lỗi: template luận 2 không hợp lệ

+2

Điều đó có thể phụ thuộc vào định nghĩa của TemplateClass <>. Bạn có thể đăng bài đó không? – hatboyzero

+2

@hatboyzero nó không – sehe

+0

Tôi nghĩ rằng sự hiểu lầm cơ bản ở đây là bạn giả định các 'const' sửa đổi tự động làm cho một cái gì đó một' constexpr'. Các mảng Char không phải là hằng số biên dịch; chúng không được biết cho đến khi thời gian liên kết. – tenfour

Trả lời

5

Sự khác biệt là vì const ảnh hưởng đến liên kết. Nó hoạt động nếu bạn thêm extern. Điều đó nói rằng, theo như tôi có thể nói:

14.3.2 Template non-type arguments [temp.arg.nontype]

A template-argument for a non-type, non-template template-parameter shall be one of:

  • an integral constant expression (including a constant expression of literal class type that can be used as an integral constant expression as described in 5.19); or
  • the name of a non-type template-parameter; or
  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or
  • a constant expression that evaluates to a null pointer value (4.10); or
  • a constant expression that evaluates to a null member pointer value (4.11); or
  • a pointer to member expressed as described in 5.3.1.

cũng nên hoạt động mà không cần extern. Đối tượng được phép có liên kết nội bộ, nhưng trình biên dịch của bạn chưa hỗ trợ. Đây là một trong những thay đổi trong C++ 11, tiêu chuẩn C++ trước đó không cho phép nó.

+1

Ok, điều này có vẻ là vấn đề. Tốt như tôi đã nhận thấy bây giờ, cho phép liên kết nội bộ là mới (C++ 11?). Nhưng tại sao nó không được phép? – ejoerns

+1

@ejoerns Tôi không biết đây có phải là toàn bộ lý do hay không, nhưng chỉ cho phép các đối tượng và chức năng có liên kết bên ngoài giúp dễ dàng đảm bảo rằng tất cả các tên bị xáo trộn của các mẫu riêng biệt khác nhau. – hvd

+1

@ejoerns Bạn nói đúng là nó mới trong C++ 11, nhân tiện. Tôi chỉ cần kiểm tra. – hvd

1

Lỗi cho biết: kết quả không phải là một biểu thức liên tục (nó được biết tại thời gian liên kết, nhưng không phải thời gian biên dịch).

Dưới đây là một ví dụ mà sẽ công việc:

typedef const char *nontype_t; 
template <nontype_t> struct Y {}; 

char hello[] = "hello"; 
constexpr char* world = hello; 

int main() 
{ 
    Y<hello> a; 
} 
+0

Tôi không hiểu. Làm thế nào là con trỏ-to-char nữa con trỏ đến đối tượng hơn con trỏ-to-const-char? – hvd

+1

Vậy tại sao bạn trích dẫn một phần của tiêu chuẩn liên quan đến loại nào được chấp nhận? – hvd

+0

Nó có thể là một đối tượng có thời gian lưu trữ tĩnh và tùy thuộc vào loại tham số mẫu, sau đó nó sẽ hợp lệ. Vấn đề có thể là kiểu tham số là một mảng với kiểu char không const. –

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