#include <iostream>
#include <string>
using namespace std;

struct foo{
  string bar;
  // foo() = delete; // Nothing changes if this is uncommented
  foo(const string& bar) : bar(bar) { }
  
  void operator()(){
    cout << "my bar is \"" << bar << '"' << endl;
  }
};

void hmm1(string str){
  foo(str)();             // Interpreted as 'foo str();', so nothing more
                          // than a declaration of 'str' as type foo
}
// warning: unused parameter ‘str’ [-Wunused-parameter]
//  void hmm1(string str){
void hmm2(string str){
  foo(str).operator()();  // Both of these construct a foo object 
  (foo(str))();           // and call its () operator
}
void hmm3(string str){
  foo{str}();             // Same as in hmm2
}
int main(){
  hmm1("this is hmm1");
  foo("similar format to hmm1")();
  
  hmm2("these are hmm2");

  hmm3("this is hmm3");
  foo{"similar format to hmm3"}();

	return 0;
}


/*
void compilation_error(){
  string x("lol");
  foo(x)();
}
// error: ‘foo x()’ redeclared as different kind of symbol
//    foo(x)();
//           ^
// note: previous declaration ‘std::__cxx11::string x’
//    string x("lol");
*/

void but_this_is_okay(){
  string x("lol");
  foo{x}();
}