I am using GCC 4.8 to compile the following code:
#include <memory>
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args) {
return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
}
struct S {
template<class... Args>
static std::unique_ptr<S> create(Args&&... args) {
return make_unique<S>(std::forward<Args>(args)...);
}
private: // if I remove this line, then the compilation is OK
S(int) {}
S() = default;
};
int main() {
auto s1 = S::create(); // OK
auto s2 = S::create(0); // Compilation error
}
Can anyone explain me the reason of this error from the compiler?
main.cpp: In instantiation of 'std::unique_ptr make_unique(Args&& ...) [with T = S; Args = {int}]':
main.cpp:11:58: required from 'static std::unique_ptr S::create(Args&& ...) [with Args = {int}]'
main.cpp:20:26: required from here
main.cpp:14:5: error: 'S::S(int)' is private
S(int) {} ^
main.cpp:5:65: error: within this context return std::unique_ptr(new T{std::forward(args)...});
^
1. Understand the language well. Arrays decay to pointers in both C and C++, but not always as can be seen from the above example. One of the most important ways to avoid compilation failures in any language is to understand the language well.
Compiler errors are due to inaccuracies in code, where the compiler throws an error to alert you to something which will not compile, and therefore cannot be run. An example of a compiler error would be: int = "this is not an int"; Hope that helps.
It was not a compiler bug. It was caused by a misunderstanding of the way arguments to unprototyped functions were automatically promoted. This is actually a subtle point, obscure and easily misunderstood. Most examples I have seen of people blaming the compiler are much sillier.
Can anyone explain me the reason of this error from the compiler?
The constructor which takes int
is declared to be private
which is why it is giving compilation error. Note that the constructor is getting invoked from make_unique
(which doesn't have access to private members), not from create
.
However, you're probably wondering why the first call to to create()
compiles fine, I think it is because GCC has bug. It should not compile even in this case, because the default constructor is declared to be private
as well. Clang correctly gives error for both calls (see this).
Anyway, if you want to keep them private
, then make make_unique
a friend of the class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With