Removing unused overload causes a compilation error?

I searched to remove some unused overloads and caused a compilation error, which, according to the compiler, was a template replacement error. But I thought, “Substitution error is not an error,” and anyway, why would this lead to overload?

Simple beginnings:

#include <string>

int ParseInt(const char *);
int ParseInt(std::string);

bool F(int(*)(const char *));

bool User() {
  return F(ParseInt);
}

Here user () calls F with the address of the parsing procedure. All is well. ParseInt is overloaded, but only one overload is consistent with the F signature.

Enter template overload F:

bool F(int(*)(const char *));

template <typename T>
struct MetaDeduce {
  typedef typename T::X type;
};

template <typename T>
typename MetaDeduce<T>::type F(const T&);

Now there is this weird overload of pattern F, but that's fine, because function pointers don't have elements named X anyway. Everything compiles, everything is fine.

TILL....

#include <string>

int ParseInt(const char *);
// int ParseInt(std::string);  // commenting this out caused a compiler error!

bool F(int(*)(const char *));

template <typename T>
struct MetaDeduce {
  typedef typename T::X type;
};

template <typename T>
typename MetaDeduce<T>::type F(const T&);

bool User() {
  return F(ParseInt);
}

As seen on godbolt ( http://goo.gl/2Yd04p ), this causes a strange compilation error:

10 : error: type 'int (const char *)' cannot be used prior to '::'
     because it has no members
typedef typename T::X type;
^
14 : note: in instantiation of template class 'MetaDeduce<int (const char *)>'
     requested here
typename MetaDeduce<T>::type F(const T&);
^

??? , , ? , , ! ?

+4
1

  • SFINAE . MetaDeduce<T> typename MetaDeduce<T>::type . SFINAE typename T::X, ParseInt(std::string).

    template <typename T>
    typename T::X F(const T&);
    

Live Example ( , , )

  1. , typename MetaDeduct<T>::type , ParseInt? , , , F ParseInt s. , F bool, .

    int ParseInt(const char *);
    int ParseInt(std::string);
    
    template <typename T>
    bool F(T const&);
    
    bool User() { return F(ParseInt); } // error, cannot deduce template argument
    

Live

ParseInt F(ParseInt) , ParseInt T. ( ), - F(int(*)(const char*)) ( ParseInt(const char*)). , - , , , typename MetaDeduce<T>::type.

, ParseInt . , , , .

, , . .

+4

Source: https://habr.com/ru/post/1625388/


All Articles