Using decltype with a statement using search without ADL

I have the following (far-fetched) code:

#include <utility>

namespace N
{
  struct A {};
  struct B {};
}

namespace operators
{
  bool operator|(N::A, N::B) { return true; };
}

namespace details
{
  using namespace operators;

  template<typename T, typename U>
  using UnionResultType = decltype(std::declval<T>() | std::declval<U>());
}

int main()
{
  {
    using namespace operators;
    using UnionAB = decltype(std::declval<N::A>() | std::declval<N::B>());
    static_assert(std::is_same<UnionAB, bool>::value);
  }

  {
    using UnionAB = details::UnionResultType<N::A, N::B>;
  }

  return 0;
}

GCC has a problem compiling the declaration UnionABin the second block:

operators.cpp: In substitution of ‘template<class T, class U> using UnionResultType = decltype
((declval<T>() | declval<U>())) [with T = N::A; U = N::B]’:
operators.cpp:31:56:   required from here
operators.cpp:19:54: error: no match foroperator|’ (operand types are ‘N::A’ and ‘N::B’)
using UnionResultType = decltype(std::declval<T>() | std::declval<U>());

Although it does UnionResultTypeexist in the region defining the boilerplate using namespace operators, GCC cannot find operator overload.

I am using GCC 7.2.0 (C ++ 11, 14 and 17, everyone has the same problems).

Is there some kind of problem in the code, or is it a compiler problem? If this is a compiler issue, is this a known issue?

+4
source share

Source: https://habr.com/ru/post/1689473/


All Articles