Sự cố trong GCC / C ++ 17 với lớp mẫu mẫu


10

Hãy xem xét 2 tình trạng quá tải sau đây

template<typename T>
bool test() {
    return true;
}

template<template<typename ...> class T>
bool test() {
    return false;
}

Cái thứ nhất hoạt động cho các lớp thông thường, trong khi cái thứ hai hoạt động cho các mẫu không được khởi tạo. Ví dụ:

    std::cout<<test<int>()<<std::endl; <-- this yields 1
    std::cout<<test<std::list>()<<std::endl; <--this yields 0

Bây giờ hãy xem xét chức năng mẫu sau:

template<typename U>
bool templfun(){
    struct A{
        bool f(){
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>();  // <-- this is ok
}

Trong GCC, nó cung cấp một lỗi cho độ phân giải quá tải mơ hồ, trong khi Clang biên dịch. Thật thú vị, cuộc gọi thứ hai để kiểm tra () không tạo ra lỗi (ngay cả trong GCC). Hơn nữa, nếu tôi loại bỏ template<typename U>thứ trên đầu templfun, gcc sẽ ngừng phàn nàn.

Đây có phải là một lỗi với GCC hay nó là mã bất hợp pháp?

Câu trả lời:


4

GCC là sai; struct Alà một thực thể templated nhưng rõ ràng không phải là một mẫu (vì nó không bắt đầu bằng một templatetừ khóa), vì vậy không có sự mơ hồ.

Để xác nhận, chúng ta có thể đổi tên tham số loại để thấy rằng G ++ đang cố sử dụng quá tải mẫu-mẫu.

template <typename X>
bool test() {
    return true;
}

template <template <typename...> class Y>
bool test() {
    return false;
}

template <typename U>
bool templfun() {
    struct A {
        bool f() {
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>(); // <-- this is ok
}

bool run() {
    return templfun<int>();
}

Đầu ra G ++: ( liên kết đến godbolt )

<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
   15 |             return test<A>(); // <-- this gives an error
      |                    ~~~~~~~^~

<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
    2 | bool test() {
      |      ^~~~

<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
    7 | bool test() {
      |      ^~~~

Rõ ràng " candidate: 'bool test() [with Y = templfun()::A]'" là không có thật.

Lưu ý rằng các kiểu cục bộ không được phép làm đối số mẫu trước C ++ 11 (xem C ++ 03 § 14.3.1.2), do đó có thể giải thích sự phức tạp của việc triển khai G ++.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.