8

Consider these two:

namespace X1
{
    A operator "" _x(unsigned long long i) { return A{i}; }
};

namespace X2
{
    B operator "" _x(unsigned long long i) { return B{i}; }
};

The x literal is defined twice, but one of them is defined in namespace X1 while another is defined in namespace X2.

According to the C++ standard, can this code be compiled?

Niall
  • 30,036
  • 10
  • 99
  • 142
Sadeq
  • 7,795
  • 4
  • 34
  • 45
  • No, i couldn't do it in Visual C++, it does not support this yet. – Sadeq Aug 22 '14 at 17:13
  • 3
    I recommend to use http://ideone.com/ , http://coliru.stacked-crooked.com/ or something equivalent online compiler. – erenon Aug 22 '14 at 17:16
  • 4
    It doesn't compile, but not for the reason you think. Make the operator accept `unsigned long long` parameter rather than `int`. – Igor Tandetnik Aug 22 '14 at 17:37

1 Answers1

12

A user-defined literal is treated as a call to operator ""X(...) where X is an identifier (for example, _x) and the ... depends on the form of the user-defined literal. Lookup of the appropriate user-defined literal operator then proceeds according to the usual rules for unqualified lookup; [lex.ext]:

2 - A user-defined-literal is treated as a call to a literal operator or literal operator template (13.5.8). To determine the form of this call for a given user-defined-literal L with ud-suffix X, the literal-operator-id whose literal suffix identifier is X is looked up in the context of L using the rules for unqualified name lookup (3.4.1). [...]

The definitions of the _x literal only conflict if both definitions are made available for unqualified lookup by a using or using namespace declaration or by entering either namespace; the conflict is only problematic if a call to the unqualified operator is actually made.

{ using namespace X1; auto o = 5_x; }          // OK; o is of type A
{ using namespace X2; auto o = 5_x; }          // OK; o is of type B
{ using namespace X1; using namespace X2; }    // OK; operator "" _x is not used
{ using namespace X1; using namespace X2; auto o = 5_x; }  // ambiguous

It would also be OK if the _x were different types of user-defined literal operators e.g. if one were an integer literal operator and the other a float literal operator.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • I'd just like to add that the corresponding `using` usage would be `using X1::operator"" _x;` and `using X2::operator"" _x;` in case anyone finds this question and is wondering. – Zorawar Oct 11 '16 at 11:16