0

How can one friend a variadic template function from a template class? Nothing I do does seems to work as the friend function declaration within the class seems to introduce an ambiguous overload for the variadic function

For example this does not work

template <typename... Args>
auto foo(Args&&... args);

template <typename T>
class Something {
public:
    template <typename... Args>
    friend auto foo(Args&&...);

private:
    int foo(int) { return 1; }
};

template <typename... Args>
auto foo(Args&&...) {}

int main() {
    foo(Something<int>{});
}

Predeclaring the function in a namespace doesn't work either.. Can this be done? I cannot depend on the function accepting the class itself as a parameter because the function is variadic and needs to accept n parameters which are instantiations of Something with different types with different reference qualifications

Note that this seems to work with gcc (even without the friend declaration) here https://wandbox.org/permlink/cVa18noVCX189566 and does not work for clang https://wandbox.org/permlink/7MqMO3lgXXp2tAWU

What is the right thing to do here? Who is right - gcc or clang?

Curious
  • 20,870
  • 8
  • 61
  • 146
  • The problem is not the variadic template here but the `auto` return type. – Holt Oct 20 '17 at 12:52
  • @Holt how so? Auto return types are allowed and I've used them before with single parameter friend functions accepting the class itself as an argument – Curious Oct 20 '17 at 12:59
  • I was just pointing out that this will also not work with a non-variadic template (e.g. `template auto foo(T)`) - This is not specific to variadic template, the problem is return type deduction with templated friend function. See e.g. https://stackoverflow.com/questions/27946528/template-friend-function-and-return-type-deduction – Holt Oct 20 '17 at 13:04
  • This can be simplified to [this](https://wandbox.org/permlink/GWNEB0tOPunlwl2C). Calling `foo` with `::` prefix [results in different error](https://wandbox.org/permlink/2ydJNr8iGcPUWb1P) indicating that we didn't actually declared `foo` as a friend properly. – user7860670 Oct 20 '17 at 13:12
  • @Holt `auto` return types work with friend declarations, for example see https://stackoverflow.com/a/41360153/5501675 – Curious Oct 20 '17 at 14:39
  • @VTT Unfortunately I need the variadic nature of the function. Currently I am using a workaround that dispatches the actual stuff that needs access to privates to another single parameter function (that I can friend) and then coalescing the results into one in the variadic function. But I would still like to know why this isn't working, and why it works in gcc – Curious Oct 20 '17 at 14:41
  • 1
    @Curious I did not say it didn't, I just narrowed the problem for you to find related or duplicate questions which explain that this would be a clang bug. – Holt Oct 20 '17 at 14:52
  • @Holt ah ok. So it seems like a clang bug :( – Curious Oct 20 '17 at 15:54

0 Answers0