Điều này có vẻ là một đối tượng khác "đang làm tốt điều đó?" câu hỏi từ gcc 6.0.0 và clang 3.7.0 hoạt động khác nhau.Chuyển tiếp đối số không loại gây ra hành vi khác nhau trên Mẫu biến số
Giả sử chúng ta có một mẫu biến mà phải mất một const char *
như mẫu đối số không và chuyên cho một con trỏ đưa ra:
constexpr char INSTANCE_NAME[]{"FOO"};
struct Struct{ void function() const { std::cout << __PRETTY_FUNCTION__; } };
std::ostream &operator <<(std::ostream &o, const Struct &) { return o << INSTANCE_NAME; }
template <const char *> char Value[]{"UNKNOWN"};
// spezialization when the pointer is INSTANCE_NAME
template < > Struct Value<INSTANCE_NAME>{};
Lưu ý rằng biến mẫu có các loại khác nhau tùy thuộc vào chuyên môn hóa. Mười chúng tôi có hai chức năng template, mỗi một mất một const char *
như mẫu đối số không và chuyển tiếp nó vào mẫu biến:
template <const char *NAME> void print()
{
std::cout << Value<NAME> << '\n';
}
template <const char *NAME> void call_function()
{
Value<NAME>.function();
}
Sau đó, kêu gọi này chức năng kết quả trong các hành vi khác nhau:
int main()
{
print<INSTANCE_NAME>();
call_function<INSTANCE_NAME>();
return 0;
}
kêu vang 3.7.0 in FOO
và void Struct::function() const
(Như tôi đã mong đợi) trong khi 6.0.0 gcc thất bại trong việc biên dịch với các lỗi dưới đây:
yêu cầu cho thành viên 'chức năng' trong 'Giá trị', mà là loại phi lớp 'char [8]'
tôi gần như chắc chắn rằng gcc thất bại trong việc mong đối số mẫu không loại NAME
để biến mẫu Value
trong hàm call_function
và vì lý do này nó chọn mẫu biến không chuyên là một với 'char [8]'
loại ...
Nó hoạt động như đang sao chép đối số mẫu. Điều này chỉ xảy ra khi gọi chức năng thành viên của đối tượng, nếu chúng tôi nhận xét nội dung của call_function
, đầu ra là FOO
không UNKNOWN
, do đó, trong chức năng print
chuyển tiếp đang hoạt động ngay cả trong gcc.
Vì vậy
- hành vi đúng là gì? (mi bet là dành cho clang)
- Làm thế nào tôi có thể mở một vé lỗi cho trình biên dịch đang làm sai?
@ BЈовић bạn có thể, miễn là 'const char *' có liên kết bên ngoài ([xem câu trả lời này] (http://stackoverflow.com/a/16402606/499359)). Với liên kết bên ngoài, nó sẽ luôn có cùng một địa chỉ; nghĩ về nó như thể nó là một 'int'. –
Chỉ cần lưu ý: có các cấu trúc hoàn toàn khác được gọi là 'FOO',' Foo' và 'foo' làm cho việc phân tích cú pháp tinh thần ví dụ của bạn trở nên khó khăn. 'MyCharP',' MyStruct' và 'myFun' hoặc tương tự sẽ dễ dàng hơn. – TartanLlama
@TartanLlama Tôi đã thay đổi tên, nhờ gợi ý :) –