【发布时间】:2018-11-24 09:28:50
【问题描述】:
这是我对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>>
{};
clang compiled happily and passed all libstdcxx's testsuite,而gcc failed to compile:
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。
问题:
- 这里哪个编译器对象是标准的?
- 这里最优雅的解决方案/解决方法是什么?我能想到的方式有点丑
【问题讨论】:
-
看来GCC试图确保
a.~B()中的表达式a的类型与B相同而不实例化函数模板wandbox.org/permlink/4rhdNq4w7MMSIkcR -
msvc也可以编译(虽然不支持
and,or,not)godbolt.org/z/b9-Ii8 -
icc 可以编译:godbolt.org/z/ktZB3w
标签: c++ language-lawyer c++17 template-meta-programming typetraits