Matthew
Matthew

Reputation: 2792

Overload operator| for fixed-size arrays?

Consider the following:

template <typename T> struct template_adapter_t {};

template <int N> struct foo_adapter_t {
  template <typename T> static foo_t<T, N> adapt(T const&);
};
template <int N> template_adapter_t< foo_adapter_t<N> > foo();

template <typename Range, typename Adapter>
auto operator|(
  Range const& range,
  template_adapter_t<Adapter>(*)())
-> decltype(Adapter::adapt(range))
{ return Adapter::adapt(range); }

(So, what is going on here... I have a 'dummy' class, template_adapter_t, that serves only as a specialization limiter, a concrete helper class foo_adapter_t, a free function foo which returns a type of template_adapter_t, and an overload of operator| that is supposed to take anything on the LHS, and a pointer to a function that takes no parameters and returns some type of template_adapter_t on the RHS.)

When I try to use this:

int const values[] = { ... };
values | foo<2>;

...I get an error about invalid operands.

However, this works:

std::vector<int>{} | foo<2>;

This also works:

template <typename Range, int N>
auto operator|(
  Range const& range,
  foo_adapter_t<N> const& adapter)
-> decltype(adapter.adapt(range))
{ return adapter.adapt(range); }

values | foo_adapter_t<4>{};

...so the problem doesn't seem to be with matching on the LHS. In both cases, the RHS is also templated, but for some reason, the one taking a struct works, but the one taking a function does not.

What am I missing that the alternate invocations work but the first one doesn't? How can I make the first form work?

Live example

Upvotes: 2

Views: 118

Answers (1)

llllllllll
llllllllll

Reputation: 16404

This is because you can't overload operators for 2 pointers. At least one of the operand should be used-defined class (See here).

In this line:

values | foo<2>;

values is a pointer to const int, foo<2> is a function pointer, thus no overloaded operator will be considered.

Upvotes: 3

Related Questions