这是我的实现is_destructible_v https://en.cppreference.com/w/cpp/types/is_destructible:
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>>
{};
clang 愉快地编译并通过了 libstdcxx 的所有测试套件 https://wandbox.org/permlink/euELPkPalqjRa4SL, while gcc 编译失败 https://wandbox.org/permlink/0U9s2TnjiT9PmOfk:
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 无法执行 SFINAEusing has_dtor = decltype(std::declval<U&>().~U());
.
问题:
- 哪个编译器反对这里的标准?
- 这里最优雅的解决方案/解决方法是什么?我能想到的办法有点难看
GCC在处理时似乎被破坏了~T()
where T
是标量类型的引用。
它接受以下代码 https://wandbox.org/permlink/WEFS5YFXTGbTog60,这显然是有问题的[表达式.伪]/2 https://timsong-cpp.github.io/cppwp/n4659/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;
}
}
It works https://wandbox.org/permlink/5qDvQGRFrglioFHa与海湾合作委员会也是如此。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)