3

Is there any way to invoke a user defined literal on lvalues?

e.g I would like to

int operator "" _xor1(int a) { return a^1; }

// Works fine
17_xor1;

auto myint = get_something_only_availabe_at_runtime();
// Any way to use _xor1 on myint?

_xor1(myint); // Doesn't work

Also, when compiling the following code at the compiler explorer, I was surprised to discover that it was all resolved at runtime, although all data is available at compile time. Why is that?

constexpr int operator "" _xor1(unsigned long long a) {
    return a^1; 
}

int main() {
    // This code resolves the user defined literal at runtime on gcc, 
    // msvc and clang - I don't see why I can't use the 
    // user defined literal at runtime?
    return 17_xor1;
}
  • 5
    Just define a normal function named `_xor1` – Igor Tandetnik Aug 16 '18 at 04:39
  • user-defined literal cannot be invoked on rvalues either . It's not an expression modifier. It is resolved at the parsing stage and the syntax is a grammatical literal (to summarize, a chracter, string, integer or floating literal) followed by the user-defined literal suffix; and the result of parsing is a *user-defined literal* which is an expression. – M.M Aug 16 '18 at 05:14
  • Your request is a bit like asking for `int foo() { return 1; } int main() { double d = foo().2; }` to generate `1.2` – M.M Aug 16 '18 at 05:15

2 Answers2

2

I'm not sure you really want to - as commented, you're probably better off defining a normal function and calling that - but you can call it using:

operator""_xor1(myInt);

See User-defined literals for more information.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
John Ilacqua
  • 906
  • 5
  • 19
  • Also note that, as documented on cppreference (https://en.cppreference.com/w/cpp/language/user_literal), `int` is not a valid argument for a user-defined literal - use `unsigned long long int` instead. – John Ilacqua Aug 16 '18 at 04:51
0

No, you cannot invoke a user-defined literal on a variable populated at runtime. Nor do you need to. Just define a standalone function that different pieces of code can invoke when needed, eg:

template <typename T>
T do_xor1(T a) { return a^1; }

int operator "" _xor1(unsigned long long a) { return do_xor1(a); }

// Works fine
17_xor1;

auto myint = get_something_only_availabe_at_runtime();
do_xor1(myint);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I think this is the better design option, but not true that "you cannot invoke a user-defined literal on a variable". – John Ilacqua Aug 16 '18 at 05:13
  • I actually do need to. I have three user-defined literal operators that all return the same user-defined class, for use in easing my programming. For reasons mostly unrelated to that, I need to turn (at run-time) arbitrary strings into instances of that class. If I could just tell C++ to use its compile-time logic on these strings at run-time, then I would have most of what I needed. Instead, I must manually pull the suffixes out of the strings, run a switch statement on their values, and explicitly choose one of my three operators to run. Not a big deal, but I'd rather have C++ do it... – mjwach Aug 16 '18 at 21:30
  • (But then, what I'm talking about is reusing the compile-time logic for deciding WHICH user-defined literal operator to call, whereas what you and the question-asker are talking about is reusing the contents of ONE user-defined literal operator. So I guess I'm a little bit off-topic.) – mjwach Aug 16 '18 at 21:35
  • OH ALL RIGHT I've talked myself into posing my problem as a new question: https://stackoverflow.com/questions/51885765/can-i-invoke-at-run-time-the-logic-for-choosing-which-user-defined-literal-to-ca – mjwach Aug 16 '18 at 21:49
  • @mjwach "*I need to turn (at run-time) arbitrary strings into instances of that class*" - why not just pass the string into the class's constructor, and let the class parse the string as needed? It can throw an exception if the string is not in an expected format. – Remy Lebeau Aug 16 '18 at 23:12
  • Yeah that would be a way to put all the logic in one place. But either way, I'd have to write the parsing logic myself, instead of just telling C++ "parse this the way you already know how to do". It's a little bit of extra work. – mjwach Aug 16 '18 at 23:17
  • @mjwach There is simply no way to invoke the compiler's parser at runtime. You have to do your own parsing. – Remy Lebeau Aug 16 '18 at 23:20