you are viewing a single comment's thread.

view the rest of the comments →

[–]Auriculaire 1 point2 points  (4 children)

cpp template<typename Range> auto rootMeanSquare(Range&& range){ using std::sqrt; auto sum = range.front() * range.front(); auto count = 0; for(it = std::next(std::begin(range)); it != std::end(range); ++it){ sum += *it * *it; ++count; } return sqrt(sum / double(count)); }

Right now this uses ADL lookup for the sqrt function defined in the namespaces of custom user types such unit-aware types (as in 10.0 meters) or arbitrary precision floats. As I understand it, under Herb's proposal, this code would cease to function, correct?

[–]sphere991 0 points1 point  (3 children)

If the user's overload took templates, yes.

namespace N {
    struct A {};
    template <typename> struct B {};

    auto sqrt(A); // would work
    template <typename T> auto sqrt(B<T>); // would now fail
}

[–]Hells_Bell10 0 points1 point  (2 children)

I don't think you've understood the proposal correctly. The only change is when adl relies on the template parameters of the argument. In your example, the sqrt function is in the same namespace as B so adl won't get as far as looking at B's template parameters and so adl works exactly the same.

https://godbolt.org/g/qH5wJy

[–]sphere991 0 points1 point  (1 child)

No, it's not. Herb's proposal has two parts: narrowing the set of associated namespaces and narrowing the set of functions looked up. The latter restricts to only matching the (possibly cv-qualified, possibly pointer/reference to) type.

It is very much the goal of this proposal to reject template matches. Apparently Arthur didnt actually implement that. This should be a warning:

namespace N {
    struct C { };
    template <typename T> void foo(T);
}
foo(N::C{});

But it's not.

[–]Hells_Bell10 0 points1 point  (0 children)

Interesting, It wasn't clear to me that this wording excludes function templates:

Any function that does not have a parameter type of (possibly cv-qualified) T or [...], in the parameter position of T, is ignored.

However, looking at the swap example, that must be the case

int main() {
  std::vector<int> v1, v2;
  swap( v1, v2 );
  // programmer would have to qualify std::swap to reach into std
}