J
Juha Nieminen
What are some new fancy tricks that you have found with C++11?
Perhaps something that was either just outright impossible with C++98
or much more difficult/laborious. (And naturally I'm not just talking
about things like "being able to write 'auto' instead of a long type
name", but less obvious tricks.)
Here are a couple to start off:
1) In C++98 it's not possible to get a compile-time constant that's
eg. the sum of the elements of an array, even if that array is const.
In C++11 it is now possible by using the new constexpr keyword.
Example C++11 code:
//---------------------------------------------------------------
#include <iostream>
namespace
{
constexpr unsigned kSizes[] = { 5, 15, 8, 4, 28, 3, 5, 17 };
const unsigned kSizesAmount = sizeof(kSizes) / sizeof(kSizes[0]);
template<unsigned index>
struct SizesTotal
{
constexpr static unsigned value()
{ return kSizes[index] + SizesTotal<index-1>::value(); }
};
template<>
struct SizesTotal<0U>
{
constexpr static unsigned value()
{ return kSizes[0]; }
};
constexpr unsigned getSizesTotal()
{ return SizesTotal<kSizesAmount - 1>::value(); }
}
int main()
{
// This is impossible in C++98:
unsigned values[getSizesTotal()];
std::cout << "'values' has " << sizeof(values)/sizeof(values[0])
<< " elements\n";
}
//---------------------------------------------------------------
2) Initializer lists and ranged loops. Technically speaking this is
possible to do in C++98, but it's more laborious:
//---------------------------------------------------------------
#include <iostream>
#include <vector>
void print(int t)
{
std::cout << t << ", ";
}
template<typename T>
void print(const T &t)
{
for(auto& i: t) print(i);
std::cout << '\n';
}
int main()
{
auto t1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << "--- t1:\n";
print(t1);
std::vector<std::vector<int>> t2[] =
{ { { 1, 2 }, { 3, 4 }, { 5, 6 } },
{ { 11, 12, 13 }, { 14, 15 } },
{ { 21 }, { 22, 23, 24, 25, 26 }, { 27, 28, 29 } },
{ { 31, 32, 33, 34, 35, 36, 37 } },
{ { 41 }, { 42 } }
};
std::cout << "--- t2:\n";
print(t2);
}
//---------------------------------------------------------------
Perhaps something that was either just outright impossible with C++98
or much more difficult/laborious. (And naturally I'm not just talking
about things like "being able to write 'auto' instead of a long type
name", but less obvious tricks.)
Here are a couple to start off:
1) In C++98 it's not possible to get a compile-time constant that's
eg. the sum of the elements of an array, even if that array is const.
In C++11 it is now possible by using the new constexpr keyword.
Example C++11 code:
//---------------------------------------------------------------
#include <iostream>
namespace
{
constexpr unsigned kSizes[] = { 5, 15, 8, 4, 28, 3, 5, 17 };
const unsigned kSizesAmount = sizeof(kSizes) / sizeof(kSizes[0]);
template<unsigned index>
struct SizesTotal
{
constexpr static unsigned value()
{ return kSizes[index] + SizesTotal<index-1>::value(); }
};
template<>
struct SizesTotal<0U>
{
constexpr static unsigned value()
{ return kSizes[0]; }
};
constexpr unsigned getSizesTotal()
{ return SizesTotal<kSizesAmount - 1>::value(); }
}
int main()
{
// This is impossible in C++98:
unsigned values[getSizesTotal()];
std::cout << "'values' has " << sizeof(values)/sizeof(values[0])
<< " elements\n";
}
//---------------------------------------------------------------
2) Initializer lists and ranged loops. Technically speaking this is
possible to do in C++98, but it's more laborious:
//---------------------------------------------------------------
#include <iostream>
#include <vector>
void print(int t)
{
std::cout << t << ", ";
}
template<typename T>
void print(const T &t)
{
for(auto& i: t) print(i);
std::cout << '\n';
}
int main()
{
auto t1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << "--- t1:\n";
print(t1);
std::vector<std::vector<int>> t2[] =
{ { { 1, 2 }, { 3, 4 }, { 5, 6 } },
{ { 11, 12, 13 }, { 14, 15 } },
{ { 21 }, { 22, 23, 24, 25, 26 }, { 27, 28, 29 } },
{ { 31, 32, 33, 34, 35, 36, 37 } },
{ { 41 }, { 42 } }
};
std::cout << "--- t2:\n";
print(t2);
}
//---------------------------------------------------------------