20

Consider the following:

#include <iostream>

namespace X
{
    void operator ""_test(unsigned long long x)
    {
        std::cout << x;
    }
}

int main()
{
    using namespace X;
    10_test;
    // 10_X::test; /* doesn't work */
}

I can refer to the user defined literal operator inside the namespace X by an explicit using namespace X;. Is there any way of referring to the literal operator without explicitly including the namespace? I tried the

10_X::test;

but of course doesn't work as the parser believes X refers to the name of the operator.

X::operator ""_test(10)

works but it's clumsy.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 1
    What's the point of a UDL if you have to explicitly qualify it? – Vittorio Romeo Mar 01 '18 at 16:36
  • If anything, I would expect it to be `10 X::_test`, since the underscore is part of the literal's name. – Quentin Mar 01 '18 at 16:37
  • 1
    Are you looking for `using X::""_test;` maybe? – Jesper Juhl Mar 01 '18 at 16:38
  • 3
    As a work around the literals could be put into their own literal namespace and then you could just include that instead of the entire namespace. You also have `using X::operator ""_test` – NathanOliver Mar 01 '18 at 16:38
  • @NathanOliver `using X::""_test` doesn't do it. I think `using X::operator ""_test` will do. – vsoftco Mar 01 '18 at 16:40
  • @Bathsheba they are two orthogonal things and udl's were "done" and useful while modules are still in a chaotic state of flux and not really that useful (in current form). Why *not* include the useful feature now while letting the not-so-useful one bake a little longer? – Jesper Juhl Mar 01 '18 at 16:42
  • @vsoftco Yep. Comment edited – NathanOliver Mar 01 '18 at 16:42
  • @JesperJuhl: Apologies, I've removed my comment as it had a typo in it. For me though, it's still about priorities. Why were folk even *thinking* about UDLs? – Bathsheba Mar 01 '18 at 16:43

1 Answers1

27
#include <iostream>

namespace X {
  inline namespace literals {
    void operator ""_test(unsigned long long x) {
      std::cout << x;
    }
  }
}

int main() {
  {
    using namespace X::literals;
    10_test;
  }
  {
    using X::operator""_test;
    10_test;
  }
}

_test is both in X and X::literals. This permits people to using namespace X::literals; without pulling in everything from X, yet within X _test is also available.

Importing an individual literal is a bit annoying.

std does this with both std::chrono and std::literals and std::chrono::literals. inline namespaces let you define subsections of your namespace that you think people would want to import as a block without getting the rest of it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524