为什么make_unique({initializer list})不能编译?

时间:2016-01-13 10:30:06

标签: c++ c++11

#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

在C ++ 11模式下也失败了
$ 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>() } );

编译呢?

0 个答案:

没有答案