Я экспериментирую с разрешением адреса перегруженной функции (bar
) в контексте другого параметра функции (foo1
/foo2
).
struct Baz {};
int bar() { return 0; }
float bar(int) { return 0.0f; }
void bar(Baz *) {}
void foo1(void (&)(Baz *)) {}
template <class T, class D>
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}
int main() {
foo1(bar); // Works
foo2<Baz>(bar); // Fails
}
Нет проблем с foo1
, который явно указывает тип bar
.
Однако foo2
, который отключает себя через SFINAE для всех, кроме одной версии bar
, не может скомпилироваться со следующим сообщением:
main.cpp:19:5: fatal error: no matching function for call to 'foo2'
foo2<Baz>(bar); // Fails
^~~~~~~~~
main.cpp:15:6: note: candidate template ignored: couldn't infer template argument 'D'
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}
^
1 error generated.
Я понимаю, что С++ не может разрешить перегруженный адрес функции и одновременно выполнять вывод аргумента шаблона.
Это причина? Можно ли скомпилировать foo2<Baz>(bar);
(или что-то подобное)?