Skip to content

Lambda constructor shows uneccesary copies #347

@andreasfertig

Description

@andreasfertig

I was made aware of the following example by @fenbf:

#include <string>

int main() {
std::string str {"Hello World"};
auto foo = [str]() { };
}

C++ Insights currently shows this transformation:

#include <string>

int main()
{
  std::string str = std::basic_string<char, std::char_traits<char>, std::allocator<char> >{"Hello World", std::allocator<char>()};
    
  class __lambda_5_12
  {
    public: 
    inline /*constexpr */ void operator()() const { }
    
    private: 
    std::basic_string<char, std::char_traits<char>, std::allocator<char> > str;
    public: 
    __lambda_5_12(std::basic_string<char, std::char_traits<char>, std::allocator<char> > _str)
    : str{_str}
    {}
  };
  
  __lambda_5_12 foo = __lambda_5_12{std::basic_string<char, std::char_traits<char>, std::allocator<char> >(str)};
}

There the constructor of __lambda_5_12 takes the arguments by copy. However, the Standard requires direct-initialization.
This is an area where the compiler is mightier than what developers can express in C++. The best option is to taken the parameters by reference or const reference. Some cases where variables are moved into captures still create an additional move.

Andreas

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions