以下代码演示了问题:
#include <type_traits>
#include <utility>
#include <memory>
#include <cstdlib>
template< std::size_t i >
struct index_t
{
};
template< typename T >
struct identity
{
using type = T;
};
struct in_place_t {};
inline
constexpr
in_place_t
in_place()
{
return {};
}
template< typename T >
constexpr
in_place_t
in_place(identity< T > = {})
{
return {};
}
template< std::size_t i >
constexpr
in_place_t
in_place(index_t< i > = {})
{
return {};
}
#include <iostream>
#define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }
struct V
{
template< typename ...A >
V(in_place_t (&)(), A &&...)
PP
template< typename T, typename ...A >
V(in_place_t (&)(identity< T >), A &&...)
PP
template< std::size_t i, typename ...A >
V(in_place_t (&)(index_t< i >), A &&...)
PP
};
int
main()
{
std::make_unique< V >(in_place< int >);
std::make_unique< V >(in_place< 2 >);
#if 0
std::make_unique< V >(in_place);
#else
std::make_unique< V, in_place_t (&)() >(in_place);
#endif
return EXIT_SUCCESS;
}
1。)#if 0
版本是解决方法并产生所需的输出:
V::V(in_place_t (&)(identity<T>), A &&...) [T = int, A = <>]
V::V(in_place_t (&)(index_t<i>), A &&...) [i = 2, A = <>]
V::V(in_place_t (&)(), A &&...) [A = <>]
2。)#if 1
版本是所需的代码,但在编译期间会产生错误:
main.cpp:74:5: error: no matching function for call to 'make_unique'
std::make_unique< V >(in_place);
^~~~~~~~~~~~~~~~~~~~~
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/unique_ptr.h:770:5: note: candidate template ignored: substitution failure [with _Tp = V]: no type named '__array' in 'std::_MakeUniq<V>'
make_unique(size_t __num)
^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/unique_ptr.h:776:5: note: candidate template ignored: substitution failure [with _Tp = V]: no type named '__invalid_type' in 'std::_MakeUniq<V>'
make_unique(_Args&&...) = delete;
^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/unique_ptr.h:764:5: note: candidate function not viable: requires 0 arguments, but 1 was provided
make_unique(_Args&&... __args)
^
1 error generated.
即。编译器无法推断构造函数的所需重载以便对nullary in_place
进行左值引用,但是可以为一元的一元版本执行此操作。
我认为它以某种方式与隐式转换规则(函数指向函数或类似的东西)相关联,但是对问题根源的确切解释是什么?
是否符合标准为std::make_unique
模板函数提供多个模板参数?
在将来std::variant
,std::optional
,std::any
和std::tuple
统一时,代码可能会有意义。