C++ 使用SFINAE测试指针类型是否可以静态转换为另一个指针类型 背景
我正在写一个可移动的C++ 使用SFINAE测试指针类型是否可以静态转换为另一个指针类型 背景,c++,c++14,sfinae,static-cast,C++,C++14,Sfinae,Static Cast,我正在写一个可移动的QScopedPointer;基本上std::unique_指针,带有一些额外的访问器。我在使用与C++11兼容的编译器之前就开始使用它,但现在我决定要正确使用它(尽管我正在重新发明轮子) 问题 让我们调用我的智能指针MyUniquePointer 我需要知道类型U*是否可以通过static\U cast转换为类型T*,具体如下: template<class T, class Cleanup> class MyUniquePointer { ... templa
QScopedPointer
;基本上std::unique_指针
,带有一些额外的访问器。我在使用与C++11兼容的编译器之前就开始使用它,但现在我决定要正确使用它(尽管我正在重新发明轮子)
问题
让我们调用我的智能指针MyUniquePointer
我需要知道类型U*
是否可以通过static\U cast
转换为类型T*
,具体如下:
template<class T, class Cleanup>
class MyUniquePointer
{
...
template<class U, class CleanupU, class = std::enable_if_t<detail::is_safely_castable<U, T>()>
MyUniquePointer(MyUniquePointer<U, CleanupU> && other) noexcept
: d(static_cast<T *>(other.release()))
{}
...
返回:
Base to base: true
Base to derived: true
Derived to base: true
Unrelated to base: false
uint32 to uint64: false
uint64 to uint32: false
Base to void: true
Void to derived: true
Convertible to base: false
Base to convertible: false
-----------
Base to base: true
Base to derived: false
Derived to base: true
Unrelated to base: false
uint32 to uint64: false
uint64 to uint32: false
Base to void: true
Void to derived: true
Convertible to base: false
Base to convertible: false
我的问题的后半部分是这个解决方案是否在正确的轨道上,更具体地说,如果| | std::is_convertible()
包括。传递时是否可以让Is_convertible
返回true
指向类型作为模板参数的指针?上面的代码包括我自己的笨拙尝试,以使其工作
脚注:我知道base\u type*
成功地转换为派生的\u type*
,但我不是编译器,无法做出这样的假设。似乎您想要:
template <typename T, typename U, typename = void>
struct is_safely_castable : std::false_type {};
template <typename T, typename U>
struct is_safely_castable<T, U,
std::void_t<decltype(static_cast<U>(std::declval<T>()))>>
: std::true_type
{};
模板
结构是_安全_可浇铸的:std::false _type{};
模板
结构是安全的浇注料
:std::true\u类型
{};
“您不能使用std::declval()的地址。”
&std::declval()
或者干脆std::declval()
?&std::declval()
,这不会起作用,但建议的变体应该可以起作用。现在看一下,我不知道std::declval()
会让你假装构造一个指向假装对象的指针。我想你会得到一个类型为T
的假指针,它什么也没有指向。哇<代码>无效\u t用于救援。我明白了,但是你能解释一下吗?这样我就可以接受这个答案了?void\t
是使用SFINAE的一种方法。只有当static\u cast
是正确的时,专门化才是正确的,否则,我们退回到一般情况,即false\u type
。
template <typename T, typename U, typename = void>
struct is_safely_castable : std::false_type {};
template <typename T, typename U>
struct is_safely_castable<T, U,
std::void_t<decltype(static_cast<U>(std::declval<T>()))>>
: std::true_type
{};