C++ 使用检测到的惯用语可销毁工具
以下是我的实施:C++ 使用检测到的惯用语可销毁工具,c++,language-lawyer,c++17,template-meta-programming,typetraits,C++,Language Lawyer,C++17,Template Meta Programming,Typetraits,以下是我的实施: 模板 结构为\u未知\u绑定\u数组:std::false\u类型 {}; 模板 结构是\u未知\u绑定\u数组:std::true\u类型 {}; 模板 使用has_dtor=decltype(std::declval().~U()); 模板 constexpr bool是可破坏的 =(标准::实验::是否检测到或标准::是否参考) 而不是\u未知\u绑定\u数组::值 而不是std::is_function_v; 模板 结构是可破坏的:std::bool\u常量 {};
模板
结构为\u未知\u绑定\u数组:std::false\u类型
{};
模板
结构是\u未知\u绑定\u数组:std::true\u类型
{};
模板
使用has_dtor=decltype(std::declval().~U());
模板
constexpr bool是可破坏的
=(标准::实验::是否检测到或标准::是否参考)
而不是\u未知\u绑定\u数组::值
而不是std::is_function_v;
模板
结构是可破坏的:std::bool\u常量
{};
,而:
prog.cc:177:47:错误:“std::declval()”不是“int&”类型
177 |使用has_dtor=decltype(std::declval().~U());
| ~~~~~~~~~~~~~~~~~~~~^
prog.cc:替换“模板使用has_dtor=decltype(declval().~U())[with T=int&;U=int&]:
因此,gcc不能在上使用has_dtor=decltype(std::declval().~U())进行SFINAE代码>
问题:
这里哪个编译器对象是标准的
这里最优雅的解决方案/解决方法是什么?我能想到的方式有点难看
在处理~T()
时,GCC似乎被破坏,其中T
是标量类型的引用
它接受了,这显然是错误的:
它也与GCC一起使用。GCC似乎试图确保a.~B()
中的a
表达式类型与B
相同。在不实例化函数模板的情况下,msvc也可以编译(尽管它不支持和,或,不)icc可以编译:
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>>
{};
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&&]':
template<typename T> using tester = decltype(int{}.~T(), char{});
tester<int&> ch;
int main() {}
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;
}
}