使用大小模板优先于指针类型的方法的方法

问题描述:

当重载一个方法时,我相信当多个匹配可用时编译器会选择更简单的匹配。使用大小模板优先于指针类型的方法的方法

考虑以下代码:

#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://*.com/questions/12924243/are-identifiers-starting-with-an-underscore-reserved-according-to-the-latest-c – druckermanly

正如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