2016-09-21 20 views
0

三項演算子を使ってC++で関数ポインタを定義すると、コンパイラエラーoverloaded function with no contextual type informationが得られます。 私は混乱しています。誰かが私にこの行動の理由を説明することができますか?三項演算子上の関数ポインタ定義

#include <string> 
#include <string.h> 
#include <iostream> 

const char *my_strstr1 (const char *__haystack, const char *__needle) { 
    std::cout << "my_strstr" << std::endl; 
    return strstr(__haystack, __needle); 
} 

const char *my_strstr2 (const char *__haystack, const char *__needle) { 
    std::cout << "my_strstr2" << std::endl; 
    return strstr(__haystack, __needle); 
} 

int main(int argc, char** argv) { 
    std::cout << "argc:" << argc << std::endl; 

    //ok 
    // const char* (*StrStr)(const char*, const char*) = strstr; 
    // const char* (*StrStr)(const char*, const char*) = (argc > 1) ? my_strstr2 : my_strstr1; 

    // error: overloaded function with no contextual type information 
    const char* (*StrStr)(const char*, const char*) = (argc > 1) ? my_strstr1 : strstr; 

    StrStr("helloworld", "h"); 

    return 0; 
} 
+0

でセクション5.16あなたが書きたいんでした:(のargc> 1)? my_strstr1:my_strstr2; – user3286661

+0

@ user3286661いいえ、OPは標準ライブラリ 'strstr'を使用します。 –

+0

それからそれをstd :: – user3286661

答えて

0

最も簡単な方法は、ちょうどあなたがラムダで欲しいとちょうどそれを使用strstr「修正」です。だから、コンパイラはあなたが欲しい1コンパイラに指示する必要がありますので1を使用すべきか分からない:Return type of '?:' (ternary conditional operator)

const char* (*StrStr)(const char*, const char*) = (argc > 1) ? my_strstr1 : (const char* (*)(const char*, const char*))strstr; 

あなたは同様のSOの質問に見てみることができます。

Working draft, Standard for Programming Language C++

+0

なぜこのコードは正しいバージョンを選択するのか知っていますか? // ok // const char *(* StrStr)(const char *、const char *)= strstr; – izual

+0

義務オペレーターは知っている、三項オペレーターは知らない。 – KIIV

+0

もっと詳しく説明したり、これに関するリンクを教えてください。 C++を使用して以来、このことについて初めて聞いたことがあります。 3q。 – izual

1

string.hで定義されたstrstrの過負荷は次のとおりです。

char *strstr(const char* str, const char* substr); 

そして<cstring>に2 strstr秒あります

const char* strstr(const char* str, const char* target); 
     char* strstr(  char* str, const char* target); 

いずれかの方法で、あなたの他の機能と一致していません。前者は間違った戻り値の型を持ち、後者は2つのオーバーロードを持ち、あなたはそれを許さない文脈でそれを使用しています。 strstr機能の複数のバージョンがあります

using F = const char*(*)(const char*, const char*); 
F std_version = [](const char* s, const char* t) -> const char* { 
    return strstr(s, t); 
}; 

F StrStr = (argc > 1) ? my_strstr1 : std_version ; 
+0

'std'は名前空間なので、この衝突はありませんか? –

+0

私はそれが一致すると思う、bczコードを正しくコンパイルすることができます。 // ok // const char *(* StrStr)(const char *、const char *)= strstr; – izual

+1

@GillBates Nope。とにかくそれを変更しました。 – Barry