Which Boost features overlap with C++11?
Replaceable by C++11 language features or libraries
- Foreach → range-based for
- Functional/Forward → Perfect forwarding (with rvalue references, variadic templates and std::forward)
- In Place Factory, Typed In Place Factory → Perfect forwarding (at least for the documented use cases)
- Lambda → Lambda expression (in non-polymorphic cases)
- Local function → Lambda expression
- Min-Max → std::minmax, std::minmax_element
- Ratio → std::ratio
- Static Assert → static_assert
- Thread → <thread>, etc (but check this question).
- Typeof → auto, decltype
- Value initialized → List-initialization (§8.5.4/3)
- Math/Special Functions →
<cmath>
, see the list below- gamma function (tgamma), log gamma function (lgamma)
- error functions (erf, erfc)
log1p
,expm1
cbrt
,hypot
acosh
,asinh
,atanh
TR1 (they are marked in the documentation if those are TR1 libraries)
- Array → std::array
- Bind → std::bind
- Enable If → std::enable_if
- Function → std::function
- Member Function → std::mem_fn
- Random → <random>
- Ref → std::ref, std::cref
- Regex → <regex>
- Result Of → std::result_of
- Smart Ptr → std::unique_ptr, std::shared_ptr, std::weak_ptr (but boost::intrusive_ptr still cannot be replaced)
- Swap (swapping arrays) → std::swap
- Tuple → std::tuple
- Type Traits → <type_traits>
- Unordered → <unordered_set>, <unordered_map>
Features back-ported from C++11:
- Atomic ← std::atomic
- Chrono ← <chrono> (see below)
- Move ← Rvalue references
Replaceable by C++17 language features:
- String_ref → std::string_view
- Filesystem → <filesystem> (Filesystem TS)
- Optional → std::optional (Library Fundamentals TS v1)
- Any → std::any (Library Fundamentals TS v1)
- Math/Special Functions →
<cmath>
(Special Math IS), see the list below- beta function
- (normal / associated / spherical) Legendre polynomials
- (normal / associated) Legendre polynomials
- Hermite polynomials
- Bessel (J / Y / I / K) functions (Y is called Neumann function in C++)
- spherical Bessel (j / y) functions
- (incomplete / complete) elliptic integrals of (first / second / third kind)
- Riemann zeta function
- exponential integral Ei
- Variant → std::variant (P0088R2)
The standard team is still working on it:
- Math Common Factor → std::experimetal::gcd, lcm (Library Fundamentals TS v2)
- Concept check → Concepts TS
- Range → Range TS
- Asio → Networking TS (sockets and timers only)
- Multiprecision → Numerics TS
- Coroutine/Coroutine2 → Coroutines TS
A large part of MPL can be trimmed down or removed using variadic templates. Some common use cases of Lexical cast can be replaced by std::to_string and std::stoX.
Some Boost libraries are related to C++11 but also have some more extensions, e.g. Boost.Functional/Hash contains hash_combine and related functions not found in C++11, Boost.Chrono has I/O and rounding and many other clocks, etc. so you may still want to take a look at the boost ones before really dismissing them.
Boost Libraries that made it into the C++ standard
There is no official list for this. You can find out about Boost incluence by reading the document that proposed the feature. Typically, it would say something like "This proposal is based on the Boost.XYZ library". Not necessarily in those words.
At least the following proposals were based, or heavily influenced on their respective boost library. Some of them were influenced by other implementations besides Boost. In some cases, it might equally appropriate to say that the boost library was influenced by the standard proposal. This is not necessarily a complete list:
<filesystem>
<shared_ptr>
<tuple>
<regex>
<thread>
<variant>
<optional>
<any>
Following proposals not (yet) accepted are similarly influenced. This list is probably even less complete:
<dl>
<process>
<stacktrace>
<networking> (C++20 should have a TS)
<static_vector><fixed_capacity_vector>
<expected><unexpected>
<safe>
<date_time>
In most cases, there are some differences between the boost library, because of lessons that were learned but could not be fixed in Boost due to backward compatibility, or because of desire to limit the scope of the proposal.
Why do I need Boost.SmartPtr for the C++ compiler that supports C++11 and later?
Why do I need Boost.SmartPtr for the C++ compiler that supports C++11 and later?
Because:
- You may need your program to compile with another compiler that doesn't support C++11 or later.
- You may not want to bother implementing
make_unique
yourself. Sure it's easy, but why do it when you can use an existing implementation? - You may want to use one of the smart pointers provided by Boost.SmartPtr besides shared pointer.
- You may already have been using it, and don't want to pay for the effort of stopping using it.
Is there a container in Boost or C++11 which act as a queue but with unique elements?
This is called queue with conflation. The naive implementation is to use something like this:
std::set<your_key_t> unique;
std::queue<your_data_t> q;
void enqueue(your_data_t x) {
if (unique.insert(x.key).second) {
q.push(std::move(x));
}
}
your_data_t dequeue(your_data_t dflt) {
if (!q.empty()) {
your_data_t x = std::move(q.front()); q.pop();
unique.erase(q.front().key);
return x;
}
else return dflt;
}
A less naive implementation may be merging incoming data with the one in the queue in some non-trivial way (say overwriting) instead of just dropping updates.
C++ wrapper for boost/c++11
Your solution looks fine to me; the only problem will be (as Chet mentions) in the cases where the Boost and C++11 interfaces and/or implementations differ.
In fact, I do that in the Boost.Algorithms library (new in the upcoming 1.50 release)
namespace boost { namespace algorithm {
#if __cplusplus >= 201103L
using std::find_if_not; // Section 25.2.5
#else
template<typename InputIterator, typename Predicate>
InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( !p(*first))
break;
return first;
}
#endif
}}
More elegant boost accumulation in C++11?
There are two methods I can think of, as follows:
std::vector< double > data = {2.1, 2.2, 3.3, 4.4, 5.5};
accumulator_set< double, features< tag::tail<left> > > acc(tag::tail<left>::cache_size = 4);
for_each(data.begin(), data.end(), [&acc](double y){ acc(y); });
or
std::vector< double > data = {2.1, 2.2, 3.3, 4.4, 5.5};
accumulator_set< double, features< tag::tail<left> > > acc(tag::tail<left>::cache_size = 4);
for (auto y : data)
acc(y);
boost::any typeid optimization for C++11
No, it's not guaranteed. This assert may trigger:
assert(&typeid(int) == &typeid(int));
While it would take a pretty stupid compiler to make that fire, it could happen. In practice, it will only fail when typeid's are being compared across dynamic library boundaries:
assert(&typeid_of_int_in_lib1() == &typeid_of_int_in_lib2());
This will almost certainly trigger.
Is it smart to replace boost::thread and boost::mutex with c++11 equivalents?
There are several differences between Boost.Thread and the C++11 standard thread library:
- Boost supports thread cancellation, C++11 threads do not
- C++11 supports
std::async
, but Boost does not - Boost has a
boost::shared_mutex
for multiple-reader/single-writer locking. The analogousstd::shared_timed_mutex
is available only since C++14 (N3891), whilestd::shared_mutex
is available only since C++17 (N4508). - C++11 timeouts are different to Boost timeouts (though this should soon change now Boost.Chrono has been accepted).
- Some of the names are different (e.g.
boost::unique_future
vsstd::future
) - The argument-passing semantics of
std::thread
are different toboost::thread
--- Boost usesboost::bind
, which requires copyable arguments.std::thread
allows move-only types such asstd::unique_ptr
to be passed as arguments. Due to the use ofboost::bind
, the semantics of placeholders such as_1
in nested bind expressions can be different too. - If you don't explicitly call
join()
ordetach()
then theboost::thread
destructor and assignment operator will calldetach()
on the thread object being destroyed/assigned to. With a C++11std::thread
object, this will result in a call tostd::terminate()
and abort the application.
To clarify the point about move-only parameters, the following is valid C++11, and transfers the ownership of the int
from the temporary std::unique_ptr
to the parameter of f1
when the new thread is started. However, if you use boost::thread
then it won't work, as it uses boost::bind
internally, and std::unique_ptr
cannot be copied. There is also a bug in the C++11 thread library provided with GCC that prevents this working, as it uses std::bind
in the implementation there too.
void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));
If you are using Boost then you can probably switch to C++11 threads relatively painlessly if your compiler supports it (e.g. recent versions of GCC on linux have a mostly-complete implementation of the C++11 thread library available in -std=c++0x
mode).
If your compiler doesn't support C++11 threads then you may be able to get a third-party implementation such as Just::Thread, but this is still a dependency.
Related Topics
C++ #Include <Atlbase.H> Is Not Found
How to Get the CPU Usage Per Thread on Windows (Win32)
Unsequenced Value Computations (A.K.A Sequence Points)
Access Array Beyond the Limit in C and C++
Benchmarking (Python VS. C++ Using Blas) and (Numpy)
Is There a Linq Library for C++
Tools to Find Included Headers Which Are Unused
C++, How to Determine If a Windows Process Is Running
What's Up with the Thousands of Warnings in Standard Headers in Msvc -Wall
How to Declare a Vector of Atomic in C++
Convert Wstring to String Encoded in Utf-8
How to Create an Array When the Size Is a Variable Not a Constant
C++: Construction and Initialization Order Guarantees
Allowing Signed Integer Overflows in C/C++
Should I Store Entire Objects, or Pointers to Objects in Containers