2016-09-21 2 views
0

Wenn ich einen Funktionszeiger in C++ mit dem ternären Operator definieren, bekomme ich den Compilerfehler overloaded function with no contextual type information. Ich bin verwirrt. Könnte mir jemand den Grund für dieses Verhalten erklären?Funktion Zeigerdefinition auf ternären Operator

#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

Haben wollen Sie schreiben: (argc> 1)? my_strstr1: my_strstr2; – user3286661

+0

@ user3286661 Nein, OP möchte die Standardbibliothek 'strstr' verwenden. –

+0

Dann voran mit std :: – user3286661

Antwort

0

Es gibt mehr als eine Version von strstr Funktion ist. So Compiler weiß nicht, welche verwendet werden soll, so dass Sie den Compiler zu sagen haben, welche Sie wollen:

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

Sie einen Blick auf ähnliche Frage SO nehmen: Return type of '?:' (ternary conditional operator).

Und auch Abschnitt 5.16 in Working draft, Standard for Programming Language C++

+0

Warum kann dieser Code dann die richtige Version auswählen? // ok // const char * (* StrStr) (const char *, const char *) = strstr; – izual

+0

Assigment-Operator weiß, ternärer Operator nicht. – KIIV

+0

können Sie mehr erklären oder einen Link dazu teilen? Es ist das erste Mal seit ich C++ benutzt habe. 3q. – izual

1

Die Überlastung von strstr in string.h definiert ist:

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

Und in <cstring> gibt es zwei strstr s:

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

So oder so, die nicht Ihre andere Funktion überein . Ersteres hat den falschen Rückgabetyp, letzteres hat zwei Überladungen und Sie verwenden es in einem Kontext, der dies nicht zulässt.

Der einfachste Ansatz ist einfach zu „reparieren“, die strstr Sie mit einem Lambda wollen und verwenden nur das:

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

Wird dies nicht kollidieren, weil 'std' ein Namespace ist? –

+0

Ich denke, das passt, bcz der Code konnte korrekt kompiliert werden. // ok // const char * (* StrStr) (const char *, const char *) = strstr; – izual

+1

@GillBates Nein. Aber änderte es trotzdem. – Barry

Verwandte Themen