0

When I define a function pointer in C++ using the ternary operator I get the compiler error overloaded function with no contextual type information. I'm confused. Could someone explain me the reason of this behavior?

#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;
}
plasmacel
  • 8,183
  • 7
  • 53
  • 101
izual
  • 247
  • 1
  • 2
  • 6

2 Answers2

1

The overload of strstr defined in string.h is:

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

And in <cstring> there are two strstrs:

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

Either way, that doesn't match your other function. The former has the wrong return type, and the latter has two overloads and you're using it in a context that doesn't allow for that.

The simplest approach is just to "fix" which strstr you want with a lambda and just use that:

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 ;
Barry
  • 286,269
  • 29
  • 621
  • 977
0

There are more than one version of strstr function. So compiler don't know which one should be used so you have to tell the compiler which one you want:

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

You can take a look to similar SO question: Return type of '?:' (ternary conditional operator).

And also section 5.16 in Working draft, Standard for Programming Language C++

Community
  • 1
  • 1
KIIV
  • 3,534
  • 2
  • 18
  • 23
  • then why this code knows how to choose the right version? //ok // const char* (*StrStr)(const char*, const char*) = strstr; – izual Sep 21 '16 at 09:02
  • Assigment operator knows, ternary operator don't. – KIIV Sep 21 '16 at 09:03
  • can u explain more or share a link about this? It's the 1st time I heard about this since using C++. 3q. – izual Sep 21 '16 at 09:09