I compiled your code with clang v10.0.1 on Linux 5.8.6. Your code bumped into an core dump. Here are some logs of valgrind (simplified in order not to be confusing):
==12170== Conditional jump or move depends on uninitialised value(s)
==12170== at 0x49BEAFE: _M_check_length (basic_string.h:322)
==12170== by 0x49BEAFE: std::string::append(char const*) (basic_string.h:1238)
==12170== by 0x10944A: MyString::filePath::{lambda()#1}::operator()[abi:cxx11]() const (test.cc:9)
==12170== by 0x109390: MyString::MyString() (test.cc:7)
==12170== by 0x109270: main (test.cc:17)
Obviously there's something wrong with the function append. In fact your issue is that you're using oneStr before its initialization.
According to cppreference:
https://en.cppreference.com/w/cpp/language/constructor
The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:
...
3) Then, non-static data member are initialized in order of declaration in the class definition.
As a result, filePath is initialized before oneStr gets initialized. The lambda is evaluated, with this captured, with this->oneStr not initialized.
Changing the order of declaration would fix this undefined behavior:
#include <iostream>
#include <string>
class MyString
{
public:
std::string oneStr;
std::string filePath = [this] ()
{
return oneStr.append(" two");
}();
};
int main()
{
MyString str;
str.oneStr = std::string(" one");
printf("%s", str.oneStr.c_str());
}
But still you may not get expected result (maybe one two?). You will see only one printed. That's because oneStr is firstly initialized with "", then appended with " two" in MyString::MyString(); but finally assigned with " one" before printing in the main function.