18

I have stumbled across following lambda syntax, which I do not understand:

#include <iostream>

template<typename Callback>
void do_it(Callback callback) {
        callback();
}

template<typename T>
void p() {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main() {
        auto a = <:&:> { };
        p<decltype(a)>();
        do_it(<:&:> { std::cout << "Hello" << std::endl; }); //this
}

Program above produces an output:

void p() [with T = main()::__lambda0]
Hello

Could you explain, what does <:&:> {/* ... */} mean? Is it possible to declare this way a lambda which takes an argument?

Vincent Savard
  • 34,979
  • 10
  • 68
  • 73
aadam
  • 713
  • 5
  • 18

1 Answers1

42

<: and :> are digraphs. They get translated to [ and ] respectively. As such, your code is equivalent to:

auto a = [&] { };
do_it([&] { std::cout << "Hello" << std::endl; }); 

So it's just a lambda which captures everything by reference.

To declare a lambda which takes an argument like this, just add a parameter list after the capture group:

auto a = <:&:> (AType) { };

If you want whoever reads your code to hate you, you can use a mix of digraphs and trigraphs wherever possible:

auto a = <:&??)??<%>;
//       ^ same as [&]{}
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • 2
    It makes sense. It was really misleading because I don't understand who and why would use digraphs nowadays. – aadam May 19 '16 at 09:32
  • 1
    @aadam Yeah, where did you come across this code? – TartanLlama May 19 '16 at 09:33
  • 2
    @aadam: I'm sure you've come up this code yourself , possibly because you're excited to share this with others :P – Nawaz May 19 '16 at 09:35
  • 4
    @TartanLlama In this SO answer: https://stackoverflow.com/questions/10033142/c11-lambda-expressions-as-callback-functions – aadam May 19 '16 at 09:36
  • @Nawaz If I came up with this I would definitely post TartanLlama's example :) – aadam May 19 '16 at 09:38
  • 11
    Trigraphs (but not digraphs) are planned for removal in C++17, just in case you needed another reason not to use them. – user657267 May 19 '16 at 09:41
  • 1
    @aadam digraphs exist, because the default character set and/or keyboard map in some locales does not have [] or {} characters. – Elkvis May 19 '16 at 12:04
  • @Elkvis are you aware of any character sets and/or keyboard maps that are in use nowadays and do not have [] or {} characters? – aadam May 19 '16 at 12:07
  • 1
    @aadam I'm not aware of any specifics, but that is the reason they were created. I'm not sure if they're still even relevant, but not everyone uses the most up-to-date operating systems and software, so digraphs are still important to allow all developers to use the language. – Elkvis May 19 '16 at 12:51
  • For anyone reading this in the future, please note that the SO question referenced above has been edited (in the past few hours) to remove the digraphs in question. – Derrell Durrett May 19 '16 at 15:24
  • How about `<:bitand:><%%>`? – T.C. May 19 '16 at 15:25
  • *"If you want whoever reads your code to hate you"* ROFL! (or if I want to test whether my code reviewers are paying attention...) – Toby Speight May 19 '16 at 16:55
  • 1
    @TobySpeight if you actually have reviewers who make you want to test them this way, then you have a serious problem in your team. – Arne Mertz May 19 '16 at 18:42