Tự động trả về kiểu mẫu và sự mơ hồ


20

Tôi có một chức năng mẫu quá tải:

template<typename T1, typename T2>
auto overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

template<typename RT, typename T1, typename T2>
RT overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

Nếu tôi gọi nó như thế này:

auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template

mọi thứ hoạt động hoàn hảo, nhưng

auto c = overMax<int>(4, 7.2); // error

gây ra cuộc gọi mơ hồ.

Tại sao nó lại như vậy với int , và OK loại nào khác?


4
Tôi nghĩ rằng .... .... Cách trình biên dịch nhìn thấy nó, là: với int, bạn đang chỉ định typename RThay typename T1? Vì 4cũng là một int, nó có thể là một trong hai. Với double, 4không khớp trực tiếp với loại double, do đó, quá tải thứ hai được ưu tiên.
ChrisMM

Điều này có vẻ hơi khó hiểu với tôi vì bạn đang quá tải loại trả về nhưng với các mẫu có số lượng tham số khác nhau.
Người quản lý

Câu trả lời:


25

RTlà không thể khấu trừ, vì vậy khi không cung cấp nó, chỉ template<typename T1, typename T2> auto overMax(T1 a, T2 b)có thể được gọi.

Khi bạn (một phần) cung cấp một đối số mẫu, cả hai phương thức đều khả thi,

nhưng tùy thuộc vào lập luận, người ta có thể là một ứng cử viên tốt hơn:

  • Dành cho auto b = overMax<double>(4, 7.2); // uses second template

    Cả hai overMax<double, int, double>overMax<double, double>đều khả thi.
    Nhưng overMax<double, int, double>là kết hợp chính xác
    trong khi overMax<double, double>đòi hỏi intphải doublechuyển đổi.

  • Dành cho auto c = overMax<int>(4, 7.2); // Ambiguous call

    Cả hai overMax<int, int, double>overMax<int, double>đều khả thi.
    Nhưng không phải là một trận đấu tốt hơn hoặc chuyên biệt hơn, vì vậy cuộc gọi là mơ hồ.


Tại sao không phải là tốt hơn nhiều? Tôi có đúng không trong trường hợp nắm tay hơnMax <int> (4, 7.2); sẽ gây ra sự chuyển đổi từ 7.2 sang int . Và trong trường hợp thứ hai, kết quả trả về, ban đầu gấp đôi , sẽ được chuyển đổi thành int do <int> rõ ràng ?
bộ khuếch đại

1
@amoder: overMax<int>(4, 7.2)sẽ là trong trường hợp đầu tiên T1=int(được cung cấp), T2=double(suy ra) và trong trường hợp thứ hai RT=int(được cung cấp), T1=int, T2=double(suy ra). Định nghĩa của cả hai phương pháp không được sử dụng để chọn quá tải.
Jarod42

đối với tôi, trường hợp thứ hai là phù hợp, vì có chuyển đổi loại trả về cho lần đầu tiên và không có chuyển đổi nào cho lần thứ hai, phải không?
bộ khuếch đại

hmmm ... chuyển đổi loại trả về không đóng vai trò ... sau đó, vâng, cả hai cuộc gọi đều tương đương với quan điểm này
bộ khuếch đại
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.