#include <memory>
struct prov {};
struct chain : public prov{
chain(){}
chain(chain const&) = default;
chain(chain &&) = default;
explicit chain(std::initializer_list<std::shared_ptr<prov>>) {};
};
struct def : public chain {
explicit def(const char *){};
};
#if __cplusplus >= 201103L
// at least C++11
#if __cplusplus == 201103L
// C++11 but not C++14
#include <memory>
namespace std {
// Smuggle in std::make_unique from the C++14 section of <memory>
/// std::make_unique for single objects
template<typename _Tp>
struct _MakeUniq
{ typedef unique_ptr<_Tp> __single_object; };
/** Constructs an object of type @c T and wraps it in a std::unique_ptr
*
* @param __args list of arguments with which an instance of T will be constructed.
* @return std::unique_ptr holding an instance of @c T
*/
template<typename _Tp, typename... _Args>
inline typename _MakeUniq<_Tp>::__single_object
make_unique(_Args&&... __args)
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
}
#endif // exactly C++11
#elif __cplusplus >= 199711L
// A C++98 compiler is not going to accept our code anyway
#error Please compile with -std=c++0x
#else
// g++ before 4.7.0 always defines __cplusplus as 1, even with -std=c++0x
#error Please get a compiler which sets __cplusplus correctly
#endif
int main()
{
chain chn { std::make_shared<prov>() };
std::unique_ptr<chain> chp(new chain{ std::make_shared<prov>() } );
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } ); // line 63
return 0;
}
无法编译:
$ g++-530 -g -std=c++14 -Wall -pedantic -Wextra -Wformat=2 -o "chain" "chain.cc"
chain.cc: In function ‘int main()’:
chain.cc:63:70: error: no matching function for call to ‘make_unique(<brace-enclosed initializer list>)’
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } ); // line 63
^
In file included from /usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/memory:81:0,
from chain.cc:1:
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:764:5: note: candidate: typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = chain; _Args = {}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<chain>]
make_unique(_Args&&... __args)
^
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:764:5: note: candidate expects 0 arguments, 1 provided
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:770:5: note: candidate: template<class _Tp> typename std::_MakeUniq<_Tp>::__array std::make_unique(std::size_t)
make_unique(size_t __num)
^
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:770:5: note: template argument deduction/substitution failed:
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h: In substitution of ‘template<class _Tp> typename std::_MakeUniq<_Tp>::__array std::make_unique(std::size_t) [with _Tp = chain]’:
chain.cc:63:70: required from here
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:770:5: error: no type named ‘__array’ in ‘struct std::_MakeUniq<chain>’
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:776:5: note: candidate: template<class _Tp, class ... _Args> typename std::_MakeUniq<_Tp>::__invalid_type std::make_unique(_Args&& ...) <deleted>
make_unique(_Args&&...) = delete;
^
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:776:5: note: template argument deduction/substitution failed:
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h: In substitution of ‘template<class _Tp, class ... _Args> typename std::_MakeUniq<_Tp>::__invalid_type std::make_unique(_Args&& ...) [with _Tp = chain; _Args = {}]’:
chain.cc:63:70: required from here
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:776:5: error: no type named ‘__invalid_type’ in ‘struct std::_MakeUniq<chain>’
使用手动make_unique
:
$ g++-530 -g -std=c++11 -Wall -pedantic -Wextra -Wformat=2 -o "chain" "chain.cc"
chain.cc: In function ‘int main()’:
chain.cc:63:70: error: too many arguments to function ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = chain; _Args = {}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<chain>]’
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } ); // line 63
^
chain.cc:39:3: note: declared here
make_unique(_Args&&... __args)
与clang相同:
$ clang++ -g -std=c++14 -Wall -pedantic -Wextra -Wformat=2 -o "chain" "chain.cc"
chain.cc:63:15: error: no matching function for call to 'make_unique'
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } ); // line 63
^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:770:5: note: candidate template ignored: substitution failure
[with _Tp = chain]: no type named '__array' in 'std::_MakeUniq<chain>'
make_unique(size_t __num)
^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:776:5: note: candidate template ignored: substitution failure
[with _Tp = chain]: no type named '__invalid_type' in 'std::_MakeUniq<chain>'
make_unique(_Args&&...) = delete;
^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/unique_ptr.h:764:5: note: candidate function not viable: requires 0 arguments, but 1 was
provided
make_unique(_Args&&... __args)
^
与C ++ 11模式中的clang相同:
$ clang++ -g -std=c++11 -Wall -pedantic -Wextra -Wformat=2 -o "chain" "chain.cc"
chain.cc:63:15: error: no matching function for call to 'make_unique'
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } ); // line 63
^~~~~~~~~~~~~~~~~~~~~~~
chain.cc:39:3: note: candidate function not viable: requires 0 arguments, but 1 was provided
make_unique(_Args&&... __args)
如果这个编译:
auto il = { std::make_shared<prov>() };
auto chx= std::make_unique<chain> ( il );
那为什么不是这个
auto ch = std::make_unique<chain> ( { std::make_shared<prov>() } );
编译呢?