I plan to update it, to include a couple more immediately useful features of C++11, such as lambdas... and of course to update the links and correct mistakes you point out.
I'm not sure if I should touch std::initializer_list or std::tuple, because the article is for beginners. What do you think, and what features should I write about?
Finally I hope the admin is still around, because I lost my login.
Add info on std::tuple. At least note that it has defined comparsion operators and demonstrate use of std::tie to quickly define comparsion operators for structs.
struct Person
{
std::string lastName;
std::string firstName;
int age;
};
We need to define operator< which will order by last name, if they are same, by first name, and if are same too, by age (for sort or to insert it into set).
Using std::tie:
If I understand the two functions correctly, std::make_tuple will copy the objects involved. [tt]std::tie[tt] will create a tuple of references (which is likely to be completely inlined.)
Well, it does seem to me that MiNiiPaa's suggestion is rather a misuse of std::tie(), which seems to have been intended to help extract values from tuples.
That said, this is what I wrote so far on tuples, and I'm still unsure if this section actually belongs in the article. If you have ideas to improve/shorten it, I'm listening.
Tuples
C++11 introduces std::tuple which is a generalization of std::pair.
Tuples can hold an arbitrary number of elements of different types and are supported by helper functions and relational operators. As such, tuples are a convenient replacement for classic POD (Plain Old Data) structures, and are ready to be used in sorting containers such as std::set.
#include <set>
#include <string>
#include <tuple>
// the C++03 way
struct Pod
{
int i;
char c;
double d;
std::string s;
};
Pod p;
p.i = 1;
p.c = 'c';
p.d = 0.1;
p.s = "Wauchope";
std::set<Pod> sp;
// sp.insert(p); // error, operator< overloaded for Pod is missing!
// the C++11 way
std::tuple<int, char, double, std::string> ticds;
ticds = std::make_tuple(1, 'c', 0.1, "Grizedale");
std::get<3>(ticds) = "Wauchope"; // change element at index 3
std::set<decltype (ticds)> st;
st.insert(ticds); // works out of the box!
// tuple test drive
std::tuple<int> ti {21};
std::tuple<int, char> tic {22, 'A'};
std::tuple<int, char, float> ticf {23, 'B', 0.0f};
char c = std::get<1>(tic); // c == 'A'
int i;
float f = 0.5f;
std::tie(i, c, std::ignore) = ticf;
// i == 23
// c == 'B'
// f == 0.5f
For the above example, Pod's missing operator< overload can be easily provided by using tuple's helper function std::tie, which is usually used to extract a tuple's elements. Here it will be used to construct a temporary tuple.
Because the return value of std::tie is a tuple, the default relational operators provided for std::tuple will kick in and do the remaining work for us.
Example:
1 2 3 4
booloperator < (const Pod &p1, const Pod &p2)
{
return std::tie(p1.i, p1.c, p1.d, p1.s) < std::tie(p2.i, p2.c, p2.d, p2.s);
}
Well, it does seem to me that MiNiiPaa's suggestion is rather a misuse of std::tie(), which seems to have been intended to help extract values from tuples.
Also:
Tuples could be used whan you need to return > 2 values from function, but there is little sense to create struct for it. They are not replacement for POD, they relates to structs like lambdas to functions.
There is neat but rarely used and maybe obscure trick: std::tie(a, b, c, d) = std::make_tuple(b, c, d, a);
I prefer bunch of assigment to not confuse anybody who will read my code.
std::tie creates a tuple of l-value references. It is used when you need to make use of assignment operator (expract values from tuple), to avoid copy of large object (my example, instead of make_tuple), or when you need a tuple of references.
MiNiiPaa used std::tie() to construct temporary tuples just to simplify the overloading of operator< for a structure, while std::tie() seems designed for multiple element extraction.
Does anybody have more comments or corrections for the article section I have posted above?
It was suggested that tuples aren't a replacement for POD. All right, then I would appreciate a better introduction so as to answer the readers' possible "why would I bother using tuples?" question.
IMHO, don't try to cover everything - for instance tuples can wait.
But highlight features which are the most immediately useful for beginners,
would encourage them to use better idioms:
In addition to what is already there:
Smart pointers (do not use raw owning pointers).
Lambda expressions, (may be) std::function<> and std::bind<>().
New integer types.
Static assertions.
nullptr.
Uniform initialization and in-class member initializers.
Some algorithms all_of/any_of/none_of, copy_if ...
Useful functions llround, to_string, stoul ...
(Based on forum faqs) Random number generators, Time utilities
to take it on an incidental off-topic tangent (it's a lounge anyway), it kind of irks me when so many people talk about C++11 features as something novel.
Tuples have been commonplace for at least 13 years, since the post-99 explosion of typelists. TR1/C++11 just picked one particularly popular version and made it a requirement.
Case in point: my corporate infrastructure library has typelists but no tuples (although it's "in progress" finally), and I am seeing over 6000 source files in the codebase that use tuples from a handful of different implementations, written by various application programmers, on as-needed basis.
It looks like yet another manual optimization keyword, for use by experts, just like restrict in C99.
constexpr functions can be called in runtime too. They just will aggressively try to make most calculation in compile time.
Constexpr values will be substituted by value in places where they are referenced (like inline for variables). If with const compiler can substiute values (and if we remove constness later it should not), with constexpr it should do that.
1 2 3 4 5 6 7
int main()
{
constexprint x = 2;
constint* a = &a; //I have doubts if pointer to constexpr variable is standard conformant.
std::cin >> const_cast<int&>(x);
std::cout << x << ' ' << *a; //x will be replaced by 2, a will point to changed value of x
}
input: 5
output: 2 5
In C++14 many limitations of constexpr functions will be removed and maybe way to provide different implementation of constexpr function to use in runtime (as constexpr implementation usually slow)
I do not think that constexpr is good for the beginner article.