Erich Keane, iCDG Software Engineer
Erich.Keane@intel.com
4 Parts: []()->retType{}
Ways to Capture:
// Function object with state:
template<typename paramType>
class IsNotEqualFinder {
const paramType& orig;
public:
IsNotEqualFinder(const paramType& o):
orig(o){}
bool operator()(const paramType& pt){
return orig != pt;
}
};
Foo original;
std::vector<Foo> list = AllFoos();
IsNotEqualFinder<Foo> finder(original);
std::vector<Foo> listWoFoo;
std::copy_if(list.begin(), list.end(),
listWoFoo.begin(), finder); //C++14 Only!
Foo original;
std::vector<Foo> list = AllFoos();
auto finder = [&orig = original]
(auto pt){ return orig != pt;};
std::vector<Foo> listWoFoo;
std::copy_if(list.begin(), list.end(),
listWoFoo.begin(), finder);
//C++11:
Foo original;
std::vector<Foo> list = AllFoos();
auto finder = [&original]
(const Foo& pt)
{ return original != pt;};
std::vector<Foo> listWoFoo;
std::copy_if(list.begin(), list.end(),
listWoFoo.begin(), finder);// Function mechanism, used only 1x,
// not necessarily nearby!
void DeleteThing(ThingType* thing){
delete thing;
}
// Calling site:
C_Call_With_Callback(myThing, &DeleteThing);
// Lambda Calling site:
C_Call_With_Callback(myThing, [](void* t){delete thing;});
// C++14 Lambda Calling Site:
C_Call_With_Callback(myThing, [](auto t){delete thing;});struct CompareThings
{
CompareAndCount() = default;
bool operator()(const Thing& t1, const Thing& t2){
return t1 < t2;
}
};
std::vector<Thing> myThings = getThings();
CompareThings ctr;
std::sort(myThings.begin(), myThings.end(), ctr);
std::vector<Thing> myThings = getThings();
auto ctr = [](const auto& t1, const auto& t2){return t1 < t2;};
std::sort(myThings.begin(), myThings.end(), ctr);
// Callback we want to use, note the context
struct OtherPart{
void CBHandler(void* context, char type, const Thing& stuff);};
// But call takes a function!
typedef void (*cb_func)(const Thing&/* stuff*/, char /*type*/, bool /*unused*/);
void StartAsyncThing(cb_func pFunc);
// Using Bind. harder to read, type erasure, everything captured by
// copy unless specified otherwise
StartAsyncThing(std::function<void(const Thing&, char, bool)>(
std::bind(&OtherPart::CBHandler, opPtr, addedContext, _2, _1)
)));
// Using Lambda:
StartAsyncThing(
[opPtr, addedContext](const Thing& stuff, char type, bool)
{ opPtr->CBHandler(addedContext, type, stuff); }
);
// Using Lambda, C++14!
StartAsyncThing(
[opPtr, addedContext](auto stuff, auto type, auto b)
{ opPtr->CBHandler(addedContext, type, stuff); }
);// Instead of:
template<typename Fn, size_t N>
void write_file(const path& name,
Fn writeFunc, array<uint8_t, N> data)
{
create_file(name);
try
{
writeFunc(data);
save_and_close(name);
log("write file done");
}
catch(...)
{
delete_file(name);
log("write file done");
throw;
}
}// This!
template<typename Fn, size_t N>
void write_file(const path& name,
Fn writeFunc, array<uint8_t, N> data)
{
scope_exit exGuard([]
{log("write file done");});
create_file(name);
scope_fail failGuard([&name]
{delete_file(name);});
scope_success successGuard([&name]
{save_and_close(name);});
writeFunc(data);
}
class scope_exit{
private:
(void*)() func;
public:
scope_exit((void*)() f) : func(f){}
~scope_exit(){func();}
};class scope_fail{
private:
(void*)() func;
int count;
public:
scope_fail((void*)() f) : func(f), count(uncaught_exceptions()){}
~scope_fail(){
if (count != uncaught_exceptions()) func();
}
};
class scope_success{
private:
(void*)() func;
int count;
public:
scope_success((void*)() f) : func(f), count(uncaught_exceptions()){}
~scope_success(){
if (count == uncaught_exceptions()) func();
}
};
// Original
void legacy_call(const char *param){...}
legacy_call("Thing being Frobbled");
string foo;
legacy_call(foo.c_str());
Partial conversion is less efficient:
void legacy_call(const string& param){...}
legacy_call("Thing being Frobbled");
string foo;
legacy_call(foo.c_str()); // results in an extra std::temporary
OR!:
void legacy_call(string_view param){...}
legacy_call("Thing being Frobbled");
string foo;
// identical, except size only calculated 1x
legacy_call(foo.c_str());
// No extra copy, size is now consistent in legacy call!
legacy_call(foo);
// std::string:
std::string other;
string_view view(other);
// Pointer + length:
void foo(char* ptr, int size)
{
string_view myView {{ptr, size}};
}
// Null terminated string (requires traversal)
char* other;
string_view view(other);// Compares to a std::string:
string_view a;
string b;
if (a == b){...}
// Compares to a null terminated string
if (a == "null term string"){...}
char* c = "null term string";
if (a == c){...}
// converts to a string:
string b = view.to_string();
// good 'find' methods:
find // find first character/substring
rfind // find last character/substring
find_first_of/find_last_of/find_first_not_of/find_last_not_of
// Additional good functions
operator[], at
front/back
size/length
empty
begin/end/cbegin/cend/rbegin/rend/crbegin/crend
data()
remove_prefix // shrink view by advancing ptr
remove_suffix // shrink view by shrinking length
substr // gets string_view to a smaller section
#include <iostream>
using std::string;
using std::cout;
using std::endl;
string extractB(const string& o)
{
auto wobraces = o.substr(1, o.size() -2);
auto justB = wobraces.substr(
wobraces.find('b') - 1);
auto justVal = justB.substr(
justB.find(':') + 1);
auto noQuotes = justVal.substr(
1, justVal.size() - 2);
return noQuotes;
}
int main()
{
string orig = "{'a':'aval','b':'bval'}";
string after = extractB(orig);
cout << after <<endl;
}
#include <iostream>
using std::string;
using std::cout;
using std::endl;
string extractB(const string& o)
{
auto wobraces = o.substr(1, o.size() -2);
auto justB = wobraces.substr(
wobraces.find('b') - 1);
auto justVal = justB.substr(
justB.find(':') + 1);
auto noQuotes = justVal.substr(
1, justVal.size() - 2);
return noQuotes;
}
int main()
{
string orig = "{'a':'aval','b':'bval'}";
string after = extractB(orig);
cout << after <<endl;
}
#include <iostream>
#include <experimental/string_view>
using std::string;
using std::cout;
using std::endl;
using std::experimental::string_view;
string extractB(string_view o)
{
auto wobraces = o.substr(1, o.size() -2);
auto justB = wobraces.substr(
wobraces.find('b') - 1);
auto justVal = justB.substr(
justB.find(':') + 1);
auto noQuotes = justVal.substr(
1, justVal.size() - 2);
return noQuotes;
}
int main()
{
string orig = "{'a':'aval','b':'bval'}";
string after = extractB(orig);
cout << after <<endl;
}
Erich.Keane@intel.com