Dependency-based overload

I have two template functions with the same name ( foo). Their signatures differ only in the type of the second parameter, which depends on the template parameter T. I was surprised that I can use this for overloading depending on whether T::Aor T::Bexisting type exists. Is this what is specifically provided for in the standard (if so, the link will be very appreciated), or am I just not firmly recognizing this as the main permission for overloading?

#include <iostream>
using namespace std;

template<typename T>
void foo(T t, typename T::A* a = 0) {
  cout << "Had an A" << endl;
}

template<typename T>
void foo(T t, typename T::B* b = 0) {
  cout << "Had a B" << endl;
}

struct HasAnAType {
  typedef int A;
};

struct HasABType {
  typedef int B;
};

struct HasAAndBTypes {
  typedef int A;
  typedef int B;
};

int main() {
  HasAnAType a;
  HasABType b;
  HasAAndBTypes ab;

  foo(a);  // prints "Had an A"
  foo(b);  // prints "Had a B"
  foo(ab); // won't compile: 'ambiguous call to overloaded function'
}

For the background, I discovered that this is possible when studying an implementation std::enable_shared_from_thisthat relies on this type of overload.

+4
3

:

- , -, .

: -, - (, ) , . , .

:

, , ( / ) , , . , , .

, SFINAE, .

+3

SFINAE void foo(T t, typename T::B* b = 0) , T::B ( T::A)

, , , .

+4

You are right that this is not a β€œregular” overload. It is called SFINAE. More information here: https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error

+1
source

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


All Articles