Toptal is a marketplace for top C++ developers, engineers, programmers, coders, architects, and consultants. Top companies and startups can hire dedicated (full-time), hourly, or part-time C++ freelancers for their mission-critical software projects.
Julie has over 20 years of experience building software applications and leading engineering teams for businesses of all sizes. She has expertise in Java, JavaScript, C, C++, and Perl, and is familiar with many popular frameworks. Recently, Julie designed and implemented a large-scale Oracle database sharding solution for Walmart.com.
Brady has three years of experience as a Software Engineer. His experience is predominantly in embedded firmware in C/C++. He also has significant experience with CICD, GitLab, Docker and scripting for test automation and Python. Brady has some experience with networking with Cisco, Type I Hypervisors and full-stack development in Apache, Flask, Go, Bootstrap.
Mike is a software architect and developer with over 25 years of experience developing large-scale mission-critical systems. He currently specializes in Java and J2EE development, C++ and C development, and embedded systems for the IoT. Also, he is an internationally recognized expert in the area of lottery gaming systems. Mike has been delivering solutions employing geographically diverse teams for the past 16 years.
Nick has been programming for more than a decade. His expertise includes React front ends, Node.js back ends, C++, games, graphics, and numerous programming languages. After starting his technology career because he wanted to make games, he has since expanded into new areas. Well-known clients include LinkedIn and Harley-Davidson. Nick loves to continuously learn new things, grow, and improve.
Ted is a software developer and programmer with 20 years of professional programming experience and close to 25 years of experience programming in C and C++ and almost as long in Python. He enjoys finding clean solutions and producing high-quality, high-value code. Ted also excels at porting and building maintainable cross-platform software and is skilled as a runtime-performance optimizer. In short, the software that Ted writes just works.
Francisco is a tech enthusiast and developer with 20+ years of experience in embedded software, hardware design, firmware, and software in general. His expertise includes a range of languages (C++, Assembly, and C), tools (Altium Designer), and libraries/APIs (wxWidgets, STM32Cube). He’s developed microcontroller units for the industrial and automotive fields. Francisco also has delivered several projects as a freelance developer and knows how to work effectively within an international team.
Jakiša has over 15 years of experience developing various types of apps for a range of operating systems. Most of his technical expertise is in C++ development, but he's also comfortable working with JavaScript, C#, and Java. As for environments, he knows the ins and outs of working with the Windows API, embedded programming, and distributed systems. He has a working knowledge of Linux/Unix systems, macOS, and mobile platforms like Android and iOS.
Abhimanyu is a machine learning expert with 15 years of experience creating predictive solutions for business and scientific applications. He’s a cross-functional technology leader, experienced in building teams and working with C-level executives. Abhimanyu has a proven technical background in computer science and software engineering with expertise in high-performance computing, big data, algorithms, databases, and distributed systems.
George is a performance-oriented engineering leader with a substantial technology background and business proficiency. He specializes in designing and implementing large-scale distributed systems with a focus on performance and reliability. Throughout his career, George has consistently identified and managed the technology and operational risks with a strong sense of end-to-end ownership for complex software products.
Darien is an accomplished software engineer with expertise in image processing, desktop application, and systems development. He worked as a research engineer in the early stages of his career, writing tools to acquire and process large volumes of scientific data. Later, he started working in the development of FDA compliant software for medical devices. Recently, he's been writing application software for a 3D printing company.
A professional developer for over 13 years, Ricardo focuses on game development, computer graphics, including rendering, computer vision, and VR/AR, artificial intelligence, and client-server systems. He is also an Unreal Engine expert with eight years of experience. Ricardo is passionate about cutting-edge technology, optimizing complex systems, and creating real-time, high-performance software.
C++ is a powerful general purpose multi-paradigm programming language. The language's immense set of features, its overall complexity, lack of elegant external tooling that other popular languages have, and access to low-level resources makes this one of the most difficult programming languages to master. Taming this mammoth beast requires much experience and wisdom.
... allows corporations to quickly assemble teams that have the right skills for specific projects.
Despite accelerating demand for coders, Toptal prides itself on almost Ivy League-level vetting.
Our clients
Creating an app for the game
Leading a digital transformation
Building a cross-platform app to be used worldwide
Drilling into real-time data creates an industry game changer
Testimonials
Tripcents wouldn't exist without Toptal. Toptal Projects enabled us to rapidly develop our foundation with a product manager, lead developer, and senior designer. In just over 60 days we went from concept to Alpha. The speed, knowledge, expertise, and flexibility is second to none. The Toptal team were as part of tripcents as any in-house team member of tripcents. They contributed and took ownership of the development just like everyone else. We will continue to use Toptal. As a startup, they are our secret weapon.
Brantley Pace, CEO & Co-Founder
Tripcents
I am more than pleased with our experience with Toptal. The professional I got to work with was on the phone with me within a couple of hours. I knew after discussing my project with him that he was the candidate I wanted. I hired him immediately and he wasted no time in getting to my project, even going the extra mile by adding some great design elements that enhanced our overall look.
Paul Fenley, Director
K Dunn & Associates
The developers I was paired with were incredible -- smart, driven, and responsive. It used to be hard to find quality engineers and consultants. Now it isn't.
Ryan Rockefeller, CEO
Radeeus
Toptal understood our project needs immediately. We were matched with an exceptional freelancer from Argentina who, from Day 1, immersed himself in our industry, blended seamlessly with our team, understood our vision, and produced top-notch results. Toptal makes connecting with superior developers and programmers very easy.
Jason Kulik, Co-Founder
ProHatch
As a small company with limited resources we can't afford to make expensive mistakes. Toptal provided us with an experienced programmer who was able to hit the ground running and begin contributing immediately. It has been a great experience and one we'd repeat again in a heartbeat.
Stuart Pocknee , Principal
Site Specific Software Solutions
We used Toptal to hire a developer with extensive Amazon Web Services experience. We interviewed four candidates, one of which turned out to be a great fit for our requirements. The process was quick and effective.
Abner Guzmán Rivera, CTO and Chief Scientist
Photo Kharma
Sergio was an awesome developer to work with. Top notch, responsive, and got the work done efficiently.
Dennis Baldwin, Chief Technologist and Co-Founder
PriceBlink
Working with Marcin is a joy. He is competent, professional, flexible, and extremely quick to understand what is required and how to implement it.
André Fischer, CTO
POSTIFY
We needed a expert engineer who could start on our project immediately. Simanas exceeded our expectations with his work. Not having to interview and chase down an expert developer was an excellent time-saver and made everyone feel more comfortable with our choice to switch platforms to utilize a more robust language. Toptal made the process easy and convenient. Toptal is now the first place we look for expert-level help.
Derek Minor, Senior VP of Web Development
Networld Media Group
Toptal's developers and architects have been both very professional and easy to work with. The solution they produced was fairly priced and top quality, reducing our time to launch. Thanks again, Toptal.
Jeremy Wessels, CEO
Kognosi
We had a great experience with Toptal. They paired us with the perfect developer for our application and made the process very easy. It was also easy to extend beyond the initial time frame, and we were able to keep the same contractor throughout our project. We definitely recommend Toptal for finding high quality talent quickly and seamlessly.
Ryan Morrissey, CTO
Applied Business Technologies, LLC
I'm incredibly impressed with Toptal. Our developer communicates with me every day, and is a very powerful coder. He's a true professional and his work is just excellent. 5 stars for Toptal.
Pietro Casoar, CEO
Ronin Play Pty Ltd
Working with Toptal has been a great experience. Prior to using them, I had spent quite some time interviewing other freelancers and wasn't finding what I needed. After engaging with Toptal, they matched me up with the perfect developer in a matter of days. The developer I'm working with not only delivers quality code, but he also makes suggestions on things that I hadn't thought of. It's clear to me that Amaury knows what he is doing. Highly recommended!
George Cheng, CEO
Bulavard, Inc.
As a Toptal qualified front-end developer, I also run my own consulting practice. When clients come to me for help filling key roles on their team, Toptal is the only place I feel comfortable recommending. Toptal's entire candidate pool is the best of the best. Toptal is the best value for money I've found in nearly half a decade of professional online work.
Ethan Brooks, CTO
Langlotz Patent & Trademark Works, Inc.
In Higgle's early days, we needed the best-in-class developers, at affordable rates, in a timely fashion. Toptal delivered!
Lara Aldag, CEO
Higgle
Toptal makes finding a candidate extremely easy and gives you peace-of-mind that they have the skills to deliver. I would definitely recommend their services to anyone looking for highly-skilled developers.
Michael Gluckman, Data Manager
Mxit
Toptal’s ability to rapidly match our project with the best developers was just superb. The developers have become part of our team, and I’m amazed at the level of professional commitment each of them has demonstrated. For those looking to work remotely with the best engineers, look no further than Toptal.
Laurent Alis, Founder
Livepress
Toptal makes finding qualified engineers a breeze. We needed an experienced ASP.NET MVC architect to guide the development of our start-up app, and Toptal had three great candidates for us in less than a week. After making our selection, the engineer was online immediately and hit the ground running. It was so much faster and easier than having to discover and vet candidates ourselves.
Jeff Kelly, Co-Founder
Concerted Solutions
We needed some short-term work in Scala, and Toptal found us a great developer within 24 hours. This simply would not have been possible via any other platform.
Franco Arda, Co-Founder
WhatAdsWork.com
Toptal offers a no-compromise solution to businesses undergoing rapid development and scale. Every engineer we've contracted through Toptal has quickly integrated into our team and held their work to the highest standard of quality while maintaining blazing development speed.
Greg Kimball, Co-Founder
nifti.com
How to Hire C++ Developers through Toptal
1
Talk to One of Our Industry Experts
A Toptal director of engineering will work with you to understand your goals, technical needs, and team dynamics.
2
Work With Hand-Selected Talent
Within days, we'll introduce you to the right C++ developer for your project. Average time to match is under 24 hours.
3
The Right Fit, Guaranteed
Work with your new C++ developer for a trial period (pay only if satisfied), ensuring they're the right fit before starting the engagement.
Find Experts With Related Skills
Access a vast pool of skilled developers in our talent network and hire the top 3% within just 48 hours.
At Toptal, we thoroughly screen our C++ developers to ensure we only match you with talent of the highest caliber. Of the more than 200,000 people who apply to join the Toptal network each year, fewer than 3% make the cut. You’ll work with engineering experts (never generalized recruiters or HR reps) to understand your goals, technical needs, and team dynamics. The end result: expert vetted talent from our network, custom matched to fit your business needs.
Can I hire C++ developers in less than 48 hours through Toptal?
Depending on availability and how fast you can progress, you could start working with a C++ developer within 48 hours of signing up.
What is the no-risk trial period for Toptal C++ developers?
We make sure that each engagement between you and your C++ developer begins with a trial period of up to two weeks. This means that you have time to confirm the engagement will be successful. If you’re completely satisfied with the results, we’ll bill you for the time and continue the engagement for as long as you’d like. If you’re not completely satisfied, you won’t be billed. From there, we can either part ways, or we can provide you with another expert who may be a better fit and with whom we will begin a second, no-risk trial.
Share
How to Hire a Great C++ Developer
C++ is a powerful, general-purpose programming language used for everything from back ends to embedded development, to desktop apps, to the very operating systems on which they run. It’s one of the very few languages to have stood the test of time, hence its well-deserved popularity and respect. But despite the efforts of the ISO C++ Standards Committee and the community to make it more programmer-friendly, it’s still arguably one of the hardest languages to master.
What’s Special About C++?
A great C++ developer is primarily a great software developer: someone with a strong problem-solving skillset and abstract thinking, the ability to find the right tools and frameworks to work with, and a passion for computer science.
There are plenty of interview questions that are language independent and designed to check the engineering prowess of the candidate; on a more basic level, the FizzBuzz question is famously effective at filtering for general coding ability. But our current focus will be very specific to C++.
If the candidate is also familiar with application development in other languages, there’s an opportunity to make the interview process even more fruitful. In that case, these first three questions will kick off an interesting discussion about the philosophies of different languages, their fundamental structures, and the advantages and disadvantages deriving from them.
Q: What is RAII and how does it relate to the fact that there is no finally keyword in C++ exception handling?
RAII stands for “resource acquisition is initialization” and is a C++-specific resource management technique. It’s based on the fact that C++ has destructors and a guarantee that they’ll be called for an object when it’s going out of scope, even in exception handling.
We don’t need finally to deal with our resources because we can wrap them up with RAII and be sure that the destructor will be called, thanks to stack unwinding.
Q: What is const-correctness? What’s its purpose (value)?
Const-correctness is the practice of specifying variables and member functions as const if they are not going to be modified or modify the state of the object, respectively. The best practice is to use const whenever possible.
const is a contract between the programmer and the compiler—it doesn’t manifest itself in the generated machine code in any way. It’s an elegant way of documenting code, making it more readable and less error-prone. Consider the following code snippet:
void PaySalary(const EmployeeId employee_id)
{
Employee& employee = company.FindEmployee(employee_id);
const auto base_salary = employee.GetBaseSalary();
const auto performance_rating = employee.MonthlyPerformance();
const auto debt = company.GetDebt(employee);
const auto total_pay = CalculateSalary(base_salary, performance_rating, debt);
company.PaySalary(employee, total_pay);
}
In this function, we acquire a reference to an object and do some further operations. One might wonder what happens with this object—in particular, when might it be modified?
The fact that GetBaseSalary and MonthlyPerformance are const member functions tells us that employee will not change its state after these calls. GetDebt takes a const Employee&, which, again, means that it hasn’t been modified. The PaySalary function, however, takes an Employee&, so that’s where we would dig in.
One should always pay extra attention to const correctness when designing a class, as it contains a message to the developers who will use it.
The Newer C++ Standards
C++ has picked up an unprecedented pace of development during the last decade. We’ve had a new standard every three years since 2011: C++11, C++14, C++17, and C++20. C++14 was a minor update over C++11, but all the others came with significant new features. The knowledge of these features is obviously necessary, but it’s also important to know their alternatives for the older standards.
Even though the vast majority of the changes in the newer standards are additions—deprecations and removals are very rare—switching a codebase to a new standard is far from easy. A proper switch, making good use of the new features, will require a lot of refactoring.
And there is still a huge amount of C++98 and C++03 code out there requiring constant care and attention. The same goes for C++11 and C++14. Besides knowing about the constexpr if (which came with C++17), a great C++ programmer should also know how to achieve the same results when stuck with an older standard.
An interesting approach to start a discussion is to ask the candidate about their favorite feature(s). A strong candidate should be able to list the most important features of a given standard, choose a favorite one, and give reasons for their choice. Of course, there is no right or wrong answer, but it quickly reveals the candidate’s feel for the language.
Q: C++11/14 introduced several significant features. Which do you find brought the biggest improvement, and why?
The auto Keyword and Range-based for Loops
The auto keyword frees us from having to explicitly specify the type of a variable when the compiler is able to deduce it. This results in cleaner, more readable, and more generic code. The range-based for loop is syntactic sugar for the most common use case.
// before C++11
for (std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) {
// after C++11
for (const auto& val : vec) {
Lambda Functions
This is a new syntax allowing developers to define function objects in-place.
std::count_if(vec.begin(), vec.end(), [](const int value) { return value < 10; });
Move Semantics
This allows us to explicitly define what it means for an object to take ownership of another object. As a result, we get to have move-only types (std::unique_ptr, std::thread), efficient shallow copy from temporaries, etc. This is a pretty big topic nicely covered by a chapter of Scott Meyers’ Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14.
Smart Pointers
C++11 introduced new smart pointers: unique_ptr, shared_ptr, and weak_ptr. unique_ptr effectively made auto_ptr obsolete.
Built-in Support for Threads
No need to struggle with OS-native and C-style libraries.
Q: Which feature of C++17 do you find most useful, and why?
Structured Bindings
This feature increases readability.
// before C++17
for (const auto& name_and_id : name_to_id) {
const auto& name = name_and_id.first;
const auto& id = name_and_id.second;
// after C++17
for (const auto& [name, id] : name_to_id) {
Compile-time if
With if constexpr, we can have different parts of code enabled depending on a compile-time condition. This makes the template metaprogramming (TMP) enable_if magic easier and nicer to achieve.
Built-in Filesystem Library
Just like with threads support in C++11, this built-in library continues to reduce the need for C++ developers to write OS-specific code. It provides an interface to work with files as such (not their content) and directories, letting developers copy them, remove them, iterate over them recursively, and so on.
Parallel STL
Parallel alternatives of much-used STL algorithms are included with C++17—an important feature ever since multi-core processors have become commonplace even on the desktop.
Q: Which feature of C++20 do you think is a nice addition, and why?
There are at least two promising C++20 features for developers.
Constraints and Concepts
This feature provides a rich new syntax to make TMP more structured, and its constructs reusable. If used properly, it can make code more readable and better-documented.
Ranges
The C++ programmers behind the ranges-v3 library advocated for its inclusion in C++20. With Unix pipe-like syntax, composable constructs, lazy range combinators, and other features, this library aims to give C++ a modern, functional look.
std::vector numbers = …;
for (auto number : numbers
| std::views::transform(abs)
| std::views::filter(is_prime)) {
…
}
// the alternative without ranges
for (auto orig_number : numbers) {
auto number = abs(orig_number);
if (!is_prime(number)) {
continue;
}
…
}
In the example above, the transform and filter operations are performed on the run, without affecting the content of the original container.
Initially, Bjarne Stroustrup, the creator of C++, had named it “C with classes,” with the motivation of supporting object-oriented programming (OOP). A general understanding of the OOP concepts and design patterns is outside the language, so checking the OOP knowledge of a C++ programmer doesn’t need to be C++-specific in most ways. However, there are some minor specificities. A very common interview question is:
Q: How does dynamic polymorphism (virtual functions) work in C++?
In C++, dynamic polymorphism is achieved through virtual functions.
class Musician
{
public:
virtual void Play() = 0;
};
class Pianist : public Musician
{
public:
virtual void Play() override {
// piano-playing logic
}
};
class Guitarist : public Musician
{
public:
void Play() override {
// guitar-playing logic
}
};
void AskToPlay(Musician* musician)
{
musician->Play();
}
The polymorphism (from the Greek poly, meaning “many,” and morph, meaning “shape”) here is that AskToPlay behaves in different ways depending on the type of the object musician points to (it can be either a Pianist or a Guitarist). The problem is that C++ code has to compile into a machine code that has a fixed set of instructions for each, including and especially the AskToPlay function. Those instructions have to choose where to jump (call) at run-time, to Pianist::Play or Guitarist::Play.
The most common and efficient approach for the compiler is to use virtual tables (or vtables). A virtual table is an array of addresses to virtual functions. Each class has its own vtable, and each instance of that class has a pointer to it. In our example, the call to Play actually becomes a call to a function that resides at the address written in the first entry of the vtable that *musician points to. If it had been instantiated as a Pianist, its pointer to vtable would have been set to Pianist’s vtable, and we’d end up calling the right function.
Another specificity comes from the fact that C++ supports multiple inheritance and there is no formal distinction between an interface and a class. The classic question of the diamond problem is a good starter to discuss that.
Being a multiparadigm programming language, C++ also supports functional programming (FP), which has become an even bigger deal after the ranges were introduced in the C++20 standard. It has brought C++ closer to the other, more FP-friendly (or FP-focused) languages from the point of view of the expressiveness and readability of the functional code. An example of a starter question would be:
Q: How do lambda functions work?
The compiler generates a functor class with an operator() with the body of the lambda, and with members to store the copies of or references to the captured variables of the lambda. Here’s an example.
It’s the same as with the other question regarding the virtual functions: Either the candidate has looked under the hood and knows exactly how it works, or it’s a good place to start a general discussion with some follow-up questions like Where do they mostly come in handy? and What was C++ programming like before lambda functions?.
Template meta-programming is yet another paradigm supported by C++. It encompasses a number of useful features, which have been accompanied by better alternatives introduced in newer standards. New features like constexpr and concepts make TMP less puzzling, but then again, there is still a lot of production code with puzzles. A famous TMP puzzle question is:
Q: How can you calculate _n_th Fibonacci number at compile-time?
With the newer standards, it’s as trivial as having a constexpr specifier in the beginning of the recursive implementation.
template
struct Fibo
{
static const int value = Fibo::value + Fibo::value;
};
template <>
struct Fibo<1>
{
static const int value = 1;
};
template <>
struct Fibo<0>
{
static const int value = 0;
};
STL, Data Structures, and Algorithms
The Standard Template Library (STL) is a library built into C++. It’s been with C++ for so long now that it’s hard to segregate it from the core language. STL brings C++ developers four kinds of features:
Containers—implementations of some fundamental data structures, like vector, list, map, and unordered_map
Algorithms—implementations of some fundamental algorithms, like sort, binary_search, transform, and partition
Iterators—an abstraction of containers for algorithms to work with
Functors—a means to customize algorithms even more
STL’s design and philosophy are unique and quite extensive. Any decent C++ programmer must have strong knowledge of STL, but the question is, to which extent? The first level would be the so-called user level knowledge. That’s when the candidate knows at least the most popular containers and algorithms, how and when to use them. The next three are some classic questions to check this:
Q: What are the differences between list and vector? How should C++ developers choose among them?
Both list and vector are sequential containers but based on different data structures. list is based on a doubly linked list, whereas vector contains a raw array.
The advantages are split between them. vector has the advantages of storing the data consecutively, with no memory overhead and constant-time indexed access. In contrast, list has constant-time insertion and removal at any position, and supports features like splice, merge, and in-place sort and reverse.
As a result, vector is more popular and most of the time is the right choice. list will be the better choice in some corner cases, like when dealing with heavy-to-copy objects, so that developers can keep them in order, or move from one container to another by just manipulating their node connections.
Q: How can you remove all _42_s from a vector? What about a list?
The trivial approach would be to iterate over the container and erase each occurrence with the erase member function, which both containers have. This is perfectly valid in the case of a list; in fact, its remove member function does pretty much the same.
But there’s a reason why vector doesn’t have such a member function. This approach is quite inefficient because of vector’s underlying data structure. The elements of vector are consecutive in the memory, so erasing an element means shifting all subsequent elements back by one position. That will result in a lot of extra copying.
First, we apply remove on the whole range, which doesn’t remove 42s from it—it just moves the others to the beginning, and it does that in the most efficient way. Instead of moving 6 to the left twice by one position (which would happen if we individually erased 42s), it only moves 6 once, by two positions. With erase then, we erase the “waste” at the end.
This idiom is nicely covered in Item 32 of Scott Meyers’ legendary Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library.
Q: What are the different types of iterators in C++? Which ones work with std::sort?
There are six categories of STL iterators: input, output, forward, bidirectional, random access, and contiguous.
The category of an iterator denotes its functionality, and those categories are inclusive. This means, saying ‘the iterator of set is bidirectional’ effectively means it’s also forward but neither random access nor contiguous.
Differences of the categories are due to the data structures of the containers. A vector iterator is a random access one, which means, unlike a set iterator, it can jump to any point in constant time. std::sort requires its parameters to be random access iterators.
These are arguably the most popular parts of STL, so any C++ programmer with at least a year of experience has met and worked with them. But that’s not enough. A high-quality C++ developer has to know not only all the STL containers and how to use them but also the abstract data structures behind them, advantages and drawbacks of each.
Also, not only should they know most of the algorithms but also their asymptotic complexities. This means C++ developers should understand, in big-O terms, the performance of standard algorithms and the data structures they use, and also the theory behind both. Questions can be very specific:
STL Container Fundamentals
Rather than test exhaustively for this knowledge, an audit-style selection of a few facts—more if needed—should make it clear enough whether the candidate is well-versed enough in these commonly-needed details.
How is [a given container, e.g., vector] implemented?
Of which category are the iterators of [a given container]?
What’s the asymptotic complexity of [a given operation, e.g., remove] on [a given container]?
vector stores the elements in an underlying array, with a size marker. When it’s full, a new, bigger storage is allocated, the elements are copied from the old storage, which then is released. Its iterators are of the random access category. The asymptotic complexity of insert (push_back) is amortized constant time, indexed access is constant time, remove is linear.
list implements a doubly linked list, storing pointers to the head and tail nodes. Its iterators are bidirectional. The complexity of insert (push_back and push_front) and remove (pop_back and pop_front) are constant time, whereas indexed access is linear.
set and map are implemented on a balanced binary search tree, more specifically a red-black tree, thus keeping the elements sorted. Their iterators are bidirectional as well. The complexities of insert, find (lookup), and remove are logarithmic. Removing an element with an iterator (erase member function) has amortized constant time complexity.
unordered_set and unordered_map are the implementations of the hash table data structure. Usually, it’s an array of so-called buckets, which are simply linked lists. A bucket is chosen for an element (during the insert or lookup) depending on its hash value and the total number of buckets. When there are so many elements in the container that the average bucket size is greater than an implementation-defined threshold (usually 1.0), the number of buckets is increased and the elements are moved to the right buckets. This process is called rehashing, and it makes the complexity of insertion amortized constant time. Find and remove have constant time complexities.
These are the most basic containers—knowledge of the above details is pretty much a must, but whether every last detail is tested for is up to the interviewer’s intuition.
Q: What’s the asymptotic complexity of [a given algorithm]?
The asymptotic complexities of some famous STL algorithms are:
Algorithm
Complexity
std::sort
O(N log(N))
std::nth_element
O(N)
std::advance
O(1) for random access iterators, and O(N) otherwise
std::binary_search
O(log(N)) for random access iterators, and O(N) otherwise
std::set_intersection
O(N)
Or, a single question to cover it all:
Q: For which containers can the insertion operation invalidate the iterators?
The elegance of this question is that it’s very hard to just remember, and the right answer requires extensive knowledge of underlying data structures of the containers with some logic.
The insertion operation might invalidate the iterators on vector, string, deque, and unordered_set/map (in case of expanding/rehashing). For list, set, and map, this is not the case thanks to their node-based data structures.
It’s standard in many developer interviews to provide a computational problem and expect the candidate to develop an algorithm to solve it. There are a bunch of great platforms for competitive C++ programming like LeetCode, HackerRank, etc. that are full of such problems.
These questions are valuable in that they check a lot of things at once. Most interviewers will start with an intentionally underspecified problem statement to test the candidate’s problem-tackling skills and ability to ask the right questions. Then, the candidate has to solve the problem, write the code, and, most importantly, do a complexity analysis.
Being good at the latter and having strong knowledge of data structures is quite enough to make wise decisions when using STL containers and algorithms, as well as writing new ones. Some might go even further and look at the actual implementation. Everyone ends up in STL code at some point, either by accident, while debugging, or willingly. If the candidate went there and managed to make sense of that gibberish, that says something about their experience, curiosity, and persistence. For example:
Q: Which sorting algorithm does std::sort implement?
The ISO C++ standard doesn’t specify the algorithm; it only sets the requirement of asymptotic complexities. The choice then depends on the implementation (i.e., that of Microsoft vs. GNU.)
Most of them don’t just settle with a single algorithm, like mergesort or quicksort. A common approach is to have a hybrid of those or choose one depending on the size. GCC, for example, implements introsort, which is a hybrid of quicksort and heapsort. It starts with the first and switches to heapsort when the length is less than the implementation-defined threshold.
C++: Time-tested, But Development Teams Must Be Skilled at Avoiding Its Pitfalls
The questions outlined in this guide cover some basic and some tricky aspects of C++ programming. But just like its possibilities, the language’s hidden surprises are limitless, and that makes it difficult to cover everything about C++ in interviews. Therefore, it is essential to evaluate a candidate’s competency, skill set, and deep understanding of C++ through their ability to convey their ideas clearly and vividly.
We hope these questions will help you as a guide in your search for a true high-quality C++ expert in either a full-time or part-time role. These rare elites may be hard to come by, but they will clearly stand out from the rest of the pack for your C++ programming team.