Keywords: C++14 | make_unique | compiler error
Abstract: This article examines the compilation error 'std::make_unique is not a member of std', which occurs due to make_unique being a C++14 feature. It analyzes the root cause, provides a custom implementation, and discusses the impact of C++11 and C++14 standard differences on smart pointer usage. Through detailed code examples and explanations, it helps developers understand how to handle unique_ptr creation across different compiler environments.
Problem Background and Error Analysis
When compiling C++-based thread pool programs, developers often encounter error messages such as error: 'make_unique' is not a member of 'std'. This typically occurs when attempting to use the std::make_unique function, as seen in example code like auto ptr1 = std::make_unique<unsigned>();. The root cause is that std::make_unique is a new feature introduced in the C++14 standard, not part of C++11. Even if a compiler supports C++11, this function will be unavailable unless C++14 or a higher standard is enabled.
C++ Standard Evolution and make_unique
The C++11 standard introduced the smart pointer std::unique_ptr but did not include a corresponding factory function make_unique. It was only in C++14, through proposal N3656, that std::make_unique was formally added to the standard library. This function is designed to provide a safer and more efficient way to create unique_ptr objects, avoiding potential memory leaks associated with direct use of the new operator. For instance, the original code auto package_ptr = make_unique<task_package_impl<R, decltype(bound_task)>>(std::move(bound_task), std::move(promise)); attempts to use this function but fails to compile in a C++11 environment.
Custom make_unique Implementation
For compilers that do not yet support C++14, a custom make_unique function can be implemented. Below is a basic example leveraging C++11 features:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}This implementation uses variadic templates and perfect forwarding to ensure arguments are correctly passed to the constructor. In practice, note that this simplified version does not handle array types; the C++14 standard's make_unique includes specialized overloads for arrays. Developers can extend the implementation as needed or refer to the full code from the standard proposal.
Compiler Configuration and Migration Advice
To avoid such errors, first check the compiler version and standard settings. For example, in GCC or Clang, enable C++14 support by adding compilation flags like -std=c++14 or -std=c++17. If a project must remain compatible with C++11, consider using a custom implementation and ensure consistent usage across the codebase. Additionally, in cross-platform development, test behavior under different compilers, as earlier versions of MSVC might provide make_unique as an extension. In the long term, migrating to C++14 or higher standards is recommended to leverage enhanced standard library features.
Conclusion and Best Practices
The issue of missing std::make_unique highlights compatibility challenges in C++ standard evolution. By understanding the error cause, adopting custom implementations, or upgrading compilers, developers can efficiently resolve compilation problems. In code, prioritizing smart pointer factory functions enhances memory safety and readability. It is advisable to specify the standard version early in projects and document dependencies to minimize integration issues later.