2017-09-11 38 views
7

Hãy xem xét ví dụ sau.Loại khấu trừ mẫu không thành công?

#include <type_traits> 
#include <iostream> 
using namespace std; 

template <typename T_> 
using Integral = typename std::enable_if<std::is_integral<T_>::value,T_>::type; 
template <typename T_> 
using NotIntegral = typename std::enable_if<!std::is_integral<T_>::value, T_>::type; 

template <typename T_> 
void printIt(const Integral<T_> &value) { cout << "Integral == " << value << endl; } 

template <typename T_> 
void printIt(const NotIntegral<T_> &value) { cout << "Non Integral == " << value << endl; } 

template <typename T_> 
void foo(const T_ &value) { printIt<T_>(value); } 

int main(int argc, char** argv) 
{ 
    printIt<int>(66); //Must explicitly provide argument type. 
    //printIt(33);  //Compiler error. No overloaded function....???? 
    foo(29.); 

    return 0; 
} 

Tại sao tôi cần phải đặt rõ ràng loại thông số mẫu? Trình biên dịch có nên tìm ra đối số loại int không?

Trả lời

11

Tại sao tôi cần phải đặt rõ ràng loại thông số mẫu?

Vì đây là non-deduced contexts.

Hãy tưởng tượng chuyên std::enable_if<std::is_integral<T_>::value,T_> để ::type đánh giá một thứ khác. Trình biên dịch không thể biết ánh xạ từ typename something<T>::type đến T.

Bạn có thể đạt được kết quả mong muốn của bạn bằng cách đặt std::enable_if như một phần của kiểu trả về, do đó quá tải không phù hợp được SFINAEd ra:

template <typename T> 
auto printIt(T x) -> std::enable_if_t<std::is_integral_v<T>, void> { /*...*/ } 

template <typename T> 
auto printIt(T x) -> std::enable_if_t<!std::is_integral_v<T>, void> { /*...*/ } 

live wandbox example

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