2016-09-21 82 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功能的多個版本。所以編譯器不知道應該用哪一個,所以你必須告訴你要哪一個編譯器:

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

你可以看看類似的SO問題:Return type of '?:' (ternary conditional operator)

而且還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

strstrstring.h定義的過載是:

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

而且在<cstring>有兩個strstr S:

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

無論哪種方式,不符合你的其他功能。前者具有錯誤的返回類型,後者有兩個重載,並且在不允許的情況下使用它。

最簡單的方法就是「修理」你想用一個lambda其中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