本文介绍了使用检测到的习语实现is_destructible的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
这是我 is_destructible_v
:
template<class T>
struct is_unknown_bound_array : std::false_type
{};
template<class T>
struct is_unknown_bound_array<T[]> : std::true_type
{};
template<typename T, typename U = std::remove_all_extents_t<T>>
using has_dtor = decltype(std::declval<U&>().~U());
template<typename T>
constexpr bool is_destructible_v
= (std::experimental::is_detected_v<has_dtor, T> or std::is_reference_v<T>)
and not is_unknown_bound_array<T>::value
and not std::is_function_v<T>;
template<typename T>
struct is_destructible : std::bool_constant<is_destructible_v<T>>
{};
c语愉快地编译并通过了所有libstdcxx的测试套件,而 gcc编译失败:
prog.cc:177:47: error: 'std::declval<int&>()' is not of type 'int&'
177 | using has_dtor = decltype(std::declval<U&>().~U());
| ~~~~~~~~~~~~~~~~~~~~^
prog.cc: In substitution of 'template<class T, class U> using has_dtor = decltype (declval<U&>().~ U()) [with T = int&&; U = int&&]':
因此,gcc无法在using has_dtor = decltype(std::declval<U&>().~U());
上执行SFINAE.
So, gcc cannot do SFINAE on using has_dtor = decltype(std::declval<U&>().~U());
.
问题:
- 哪个编译器在这里反对标准?
- 这里最优雅的解决方案/解决方法是什么?我能想到的方式有点丑陋
推荐答案
在处理~T()
时,GCC似乎已损坏,其中T
是标量类型的引用.
GCC seems to be broken when handling ~T()
where T
is a reference of scalar type.
它接受以下代码,根据 [expr.pseudo]/2 :
template<typename T> using tester = decltype(int{}.~T(), char{});
tester<int&> ch;
int main() {}
我会使用if constexpr
来实现:
template<class T>
constexpr bool my_is_destructible() {
if constexpr (std::is_reference_v<T>) {
return true;
} else if constexpr (std::is_same_v<std::remove_cv_t<T>, void>
|| std::is_function_v<T>
|| is_unknown_bound_array<T>::value ) {
return false;
} else if constexpr (std::is_object_v<T>) {
return std::experimental::is_detected_v<has_dtor, T>;
} else {
return false;
}
}
这篇关于使用检测到的习语实现is_destructible的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!