2016-11-24 17 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を出力します。

既知のサイズの配列でテンプレートメソッドが呼び出され、ポインタタイプで非テンプレートメソッドが呼び出されるようなクラスに両方のメソッドを持たせるにはどうすればよいですか?

私は次のことを試してみました:TCによって示唆されるように、

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-thelatest-c – druckermanly

答えて

1

この作品:

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; 
    } 
}; 

しかし、私は次のエラーを与える++グラム

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

関連する問題