【问题标题】:Implement is_destructible with Detected Idiom使用 Detected Idiom 实现 is_destructible
【发布时间】: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&lt;U&amp;&gt;().~U()); 上执行 SFINAE。

问题:

  1. 这里哪个编译器对象是标准的?
  2. 这里最优雅的解决方案/解决方法是什么?我能想到的方式有点丑

【问题讨论】:

标签: c++ language-lawyer c++17 template-meta-programming typetraits


【解决方案1】:

在处理~T() 时,GCC 似乎被破坏了,其中T 是标量类型的引用。

它接受following code,这显然是[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;
    }
}

works 也带有 GCC。

【讨论】:

    猜你喜欢
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多