2

Look at this example on compiler explorer:

#include <type_traits>
#include <utility>

template <typename T>
struct A {
  template <typename U>
  void test(U&& u) noexcept(noexcept(inner_test(std::forward<U>(u)))) {
    inner_test(std::forward<U>(u));
  }

 private:
  template <typename U>
  void inner_test(U&&) noexcept(
      std::is_nothrow_move_constructible_v<std::decay_t<U>> &&
      std::is_nothrow_move_assignable_v<std::decay_t<U>>
      /* and whatever */) {
    // ...
  }
};

int main() {
    A<int> a;
    a.test(3u);
}

There is a class template and two function templates. The public function is just a wrapper for the private one, which has a complex noexcept specification.

I would like to let the compiler deduce the noexcept specification for the public function, in order to avoid noexcept code duplication (it is already awful when written once...).

Clang and MSVC seem to like the code, but GCC rejects it with the following error:

<source>:7:48: error: 'inner_test' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]

Who is wrong and who is right?

Funny thing: inside noexcept(...), if you change from "&&" to "and", MSVC does not compile anymore...

The c++17 tag is mainly because I am using a couple of "_v" that are not available in c++14.

dodomorandi
  • 1,143
  • 1
  • 11
  • 18
  • There's no ADL in this example, for what it's worth. – Barry Nov 02 '18 at 14:11
  • @Barry I was unsure because in this case there there are instantiation of templates. I used ADL as term because it is exactly what GCC tells in its error. However, thank you. – dodomorandi Nov 02 '18 at 14:14
  • 1
    "I used ADL as term because it is exactly what GCC tells in its error" ... I do not see where you pasted the GCC error message in the question. That may be relevant or helpful. – Eljay Nov 02 '18 at 14:25
  • @Eljay you are right. I added the error in the question. – dodomorandi Nov 02 '18 at 14:29
  • 2
    @dodomorandi Yeah, that's unfortunate - it's a consequence of the gcc bug described in the linked question that it gives a bad error message. – Barry Nov 02 '18 at 14:46

0 Answers0