2016-11-24 59 views
6

當重載一個方法時,我相信當多個匹配可用時編譯器會選擇更簡單的匹配。使用大小模板優先於指針類型的方法的方法

考慮以下代碼:

#include <iostream> 
#include <string> 

struct A { 
    static void foo(const char *str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

int main() 
{ 
    A::foo("hello"); 
} 

輸出是1: hello。但是,如果我註釋掉static void foo(const char *str)方法,它會編譯並輸出2: hello

如何在一個類上使用兩個方法,使已知大小的數組可以調用模板方法,並且指針類型調用非模板方法?

我試過如下:

struct A { 
    template<class _Ty = char> 
    static void foo(const _Ty *str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

但G ++給了我以下錯誤:

In function 'int main()': 
17:17: error: call of overloaded 'foo(const char [6])' is ambiguous 
17:17: note: candidates are: 
6:15: note: static void A::foo(const _Ty*) [with _Ty = char] 
10:32: note: static void A::foo(const char (&)[N]) [with int N = 6] 
+3

首先,不要使用'_Ty',這是保留執行。其次,'const T * const&str'。 –

+0

謝謝,這工作!至於T和_Ty,我會恭敬地不同意。當你需要在你的文本編輯器中搜索它時,'T'是一個可怕的命名選擇。 – GaspardP

+1

這不是一個「尊重不同意」的問題,而是一個「無論如何都可能被打破」的問題。您正在使用實現保留的類型名稱。 http://stackoverflow.com/questions/12924243/are-identifiers-starting-with-an-underscore-reserved-according-to-the-latest-c – druckermanly

回答

1

正如TC建議,這個工程:

struct A { 

    template<class T, typename = typename std::enable_if<std::is_same<T, char>::value>::type> 
    static void foo(const T * const & str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

int main() 
{ 
    A::foo("hello1"); 

    const char *c = "hello2"; 
    A::foo(c); 

    char *c2 = new char[7]; 
    ::strcpy(c2, "hello3"); 
    A::foo(c2); 

    // does not compile 
    // int *c3; 
    // A::foo(c3); 
} 

輸出:

2: hello1 
1: hello2 
1: hello3 

我希望我不必模板指針方法,因爲它打開了錯誤的意外類型的大門,但我可以忍受這個解決方案。

+1

'const T *&str'就夠了嗎? – Danh

+1

如果你擔心使用意想不到的類型,你可以使用'std :: enable_if'和'std :: is_same'來驗證'T'是'char'類型,否? – druckermanly

+0

'const T *&str'確實夠用 – GaspardP