0

There is a post here asking for what I believe is equivalent for my purposes (the address of the function as opposed to the type) but the question is already 5 years old; the sole answer states that there might not be a proper solution - without suggesting a particular reason - and offers a partial solution requiring a new function explicitly calling each ADL function in question just to leverage lambda semantics.

template <typename T>
void (*get_swap())(T&, T&) {
    return [](T& x, T& y) { return swap(x, y); };
}

I could make this somewhat more generic:

template<typename... T>
void (*get_func())(T &&... t) {
    return [](T &&... u) { return func(std::forward<T>(u)...); };
}

Obviously func ought to be an argument as well - potentially a template argument - but this starts to break down.

template<typename S, typename... T>
void (*get_func())(S (*func)(T &&...), T &&... t) {
    return [](T &&... u) { return func(std::forward<T>(u)...); };
}

The answer proceeds to use get_swap like so:

auto f1 = get_swap<a::b>();

It seems like this is the end of the road: f1 is typed by an explicit instantiation of a function; ADL is out the window.

Consider std::make_tuple: you already know that std::make_tuple<T...> is callable on T &&... t and that calling std::make_tuple(std::forward<T>(t)...) is equivalent to explicitly instantiating it on T.... What if you didn't know that? Maybe some of the template arguments are values, or the arguments are packed somehow, or the best candidate happens to include some extra arguments with defaults. You could probably make an argument for RTFM, or for waiting for some kind of reflection concept to come down the pipeline, but I think it's a valid question; obviously the compiler knows the address and type of the function it resolves via ADL. If I were adding this as a feature, I wouldn't know where to begin in terms of syntax (although I would expect it to follow declval and decltype as perhaps declfunc, returning the type of the outermost call.)

In a nutshell, what I'm looking for is a way to ask, "what would you call if I supplied these arguments?" and/or "what is the type of what you would call (...)".

Meta: I intentionally left out version-specific tags in case a solution might exist in a newer version (or a proposal, etc.) For what it's worth, I'm using C++14 coming from a background of mainly C++11. This is an academic interest, at least for now. Also, I aimed for a neutral tone, but in case it sounded otherwise, I have no intention of slighting the author of the answer I cited.

John P
  • 1,463
  • 3
  • 19
  • 39

1 Answers1

0

No, C++ does not expose this.

If you had a practical use case people could provide workarounds or solutions tomthe underlyong problem. But as you are asking for a very specific feature in the abstract, the answer is C++ doesn't provide that specific feature.

You could probably rewrite a compiler to do this, but then that wouldn't be C++ anymore.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • So... "Depending on what you want to achieve I can suggest a workaround", to quote the post I linked? The purpose is type introspection, which is inherently abstract. Okay, suppose I want to call a function once with some default arguments and once with arguments I supply, because I want to test how this changes the body's behavior. Definitions with other signatures are either stubs, are subject to change, or perform some related but distinct subtask. Maybe they're tagged by algorithm and I'm comparing performances. How can I statically assert that the same candidate is used? – John P Jun 29 '18 at 13:05
  • Of course the performance is a runtime measurement, but I have to statically assert so I know that remote tests are well-formed. Otherwise I would just dig in with a debugger. If the answer is still "it can't be done", that may well be correct, but at least superficially, you don't appear to have given this much time or thought ("or solutions tomthe underlyong problem", etc.) No hard feelings. – John P Jun 29 '18 at 13:11
  • @JohnP I haven't given your question much additional thought, because I've looked at this problem before. You are asking for an abstract language feature that C++ just doesn't have. If you have a different concrete problem to solve, the right way to do it is to use the [ask question] button *with that concrete problem*. As for your example, you cannot statically assert the same candidate is used, C++ does not have that feature. If you could mess with the functions, probably, but if you can mess with the functions you can simply remove the overload insanity you describe and you'd be done. – Yakk - Adam Nevraumont Jun 29 '18 at 13:56