C++ SFINAE条件和构造函数参数类型
我遇到了以下技术,它允许在C++ SFINAE条件和构造函数参数类型,c++,templates,c++11,constructor,sfinae,C++,Templates,C++11,Constructor,Sfinae,我遇到了以下技术,它允许在T周围构造包装器对象,但是如果T可以从U构造,则可以从U类型的对象构造包装器对象: template< typename T > struct S { template< typename U, typename = std::enable_if_t< std::is_constructible< T, U >::value > > expli
T
周围构造包装器对象,但是如果T
可以从U
构造,则可以从U
类型的对象构造包装器对象:
template< typename T >
struct S {
template< typename U,
typename = std::enable_if_t<
std::is_constructible< T, U >::value > >
explicit S (U&& arg) : value (arg)
{ }
...
};
模板
结构{
模板::值>>
显式S(U&&arg):值(arg)
{ }
...
};
IIUC,在是可构造的测试中使用的U
类型可以不同于arg
的cv合格类型
尽管表达式value(arg)
有效,SFINAE测试是否可能失败
尽管表达式值(arg)有效,SFINAE测试是否可能失败
你写S
的方式:是的,这是可能的。
下面是一个最小的(非)工作示例:
#include<type_traits>
template< typename T >
struct S {
template< typename U
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
> explicit S (U&& arg) : value{arg} {}
T value;
};
struct A {};
struct B {
B(A &) {}
};
int main() {
S<B> s(A{});
}
注意使用std::forward
实际转发具有正确类型的参数。
这至少解决了上面提到的问题,它应该给你的保证,你正在寻找
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
#include<utility>
// ...
template< typename T >
struct S {
template< typename U
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
> explicit S (U&& arg) : value (std::forward<U>(arg)) { }
T value;
};