2016-03-10 15 views
6

Với this test program:Tại sao "cuộc gọi" này lại khẳng định khi thấy hai đối số thay vì chỉ là một đối số?

#include <cassert> 
#include <string> 
#include <type_traits> 

const std::string& const_string = "bla"; 
std::string const & string_const = "blabla"; 

static_assert(std::is_same<decltype(const_string), decltype(string_const)>::value, "Uhoh"); 

int main() 
{ 
    assert(std::is_same<decltype(const_string), decltype(string_const)>::value); 
} 

nào khẳng định rằng hai loại đều giống nhau ở thời gian biên dịch và khi chạy bằng assert C. Tất cả các Clang, MSVC2015, và GCC báo lỗi tương tự, vì vậy tôi khá chắc chắn it's me:

main.cpp:13:49: error: too many arguments provided to function-like macro invocation 
    assert(std::is_same<decltype(const_string), decltype(string_const)>::value); 
               ^
/usr/include/assert.h:91:10: note: macro 'assert' defined here 
# define assert(expr)             \ 
     ^

Tôi chỉ không nhìn thấy hai đối số trong assert. Hơn nữa, các static_assert hoạt động tốt ... Vì vậy, những gì đang xảy ra ở đây?

+0

Tôi tin rằng bộ tiền xử lý nhìn thấy hai "so sánh"; 'std :: is_same :: giá trị'. Không có cách nào để người tiền xử lý nói rằng họ không có. – molbdnilo

+1

** static_assert ** là từ khóa, ** khẳng định ** macro tiền xử lý. Các macro tiền xử lý phân tách các đối số bằng ',' theo cách không thông minh. Các dấu ngoặc bổ sung ngăn chặn điều này. – Youka

Trả lời

3

Đó là vì mã thông báo <>. Chúng làm rối tung bộ tiền xử lý. Hãy nhớ rằng assert là macro, không phải là hàm.

Đừng này (thêm thêm một bộ dấu ngoặc đơn):

assert((std::is_same<decltype(const_string), decltype(string_const)>::value)); 
    ^                ^
4

C Preprocessor không công nhận C++ template cú pháp, do đó mẫu dấu ngoặc <> không xem như nhóm tokens bằng vi xử lý, họ được xem như những nhân vật đơn giản.

này có nghĩa là tiền xử lý sẽ xem dấu phẩy giữa các thông số mẫu như thiết bị tách thông số vĩ mô, như thế này:

assert(
    std::is_same<decltype(const_string), 
    decltype(string_const)>::value); 

Buộc thực hiện tiền xử lý để xem biểu hiện của bạn như một tuyên bố duy nhất, chỉ đơn giản là quấn assert của bạn tham số trong một bộ thêm dấu ngoặc:

assert((std::is_same<decltype(const_string), decltype(string_const)>::value)); 

static_assert không có hạn chế này vì nó là một C++ keyword, chứ không phải là một macro tiền xử lý như assert() . Điều này có nghĩa là nó hỗ trợ đầy đủ cú pháp C++ và xem các tham số mẫu một cách chính xác.

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