Thread: Qt and C++0x lambdas: they don't seem to mix

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    63

    Qt and C++0x lambdas: they don't seem to mix

    Hello all,

    I've been playing around with the experimental lambda branch of GCC, and I'm finding lambdas to be pretty handy to have. Well, that is, unless you are using members of the Qt framework's own template library. Let's take a look at a simple example:

    Code:
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <QMap>
    using namespace std;
    
    int main()
    {
    	QMap<int,string> my_map;
    	my_map[1] = "test";
    	my_map[2] = "lolololol";
    	for_each(my_map.begin(), my_map.end(), [](pair<int, string > test){ std::cout << test.second << "\n"; std::cout << test.first << "\n";});
    	return 0;
    }
    This code results in a bunch of errors. Replacing QMap with std::map makes this work. The errors are along the lines of "no match for call ‘(main()::<lambda>(std::pair<int, std::basic_string<char> >)) (std::basic_string<char>&)’

    note: note: candidates are: main()::<lambda>(std::pair<int, std::basic_string<char> >)

    This isn't a problem for me, but for others, it might be. So I thought I'd point it out.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That has nothing to do with lambdas. The value_type of a QMap<K, V>'s iterator is simply V, not std:air<const K, V>, as with a std::map.

    This means that you cannot use for_each to iterate over a QMap if you want to access the key. If you don't want to access the key, you can do this:
    Code:
    for_each(qmap.begin(), qmap.end(), [](const std::string& s) { ... });
    Speaking of the standard map, your iteration code is very inefficient, because it copies all the strings. You want a reference there. Maybe you tried a reference and it didn't work, though? This is because the map adds const to the key.
    Code:
    typedef std::map<int, string> MapT;
    MapT my_map;
    // ...
    for_each(my_map.begin(), my_map.end(), [](const MapT::value_type &test) { ... });
    Meh. I wonder how long it will take GCC to implement the new for loop already.
    Code:
    for(const auto &test : my_map) {
      ...;
    }
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    It is inefficient, because it is just an example of whatever causes it to go wrong. But thanks for clearing up the QMap issues. Now I feel kind of silly, like thinking the sun revolves around the Earth.

Popular pages Recent additions subscribe to a feed