0

这接近于代码审查/最佳实践,但是……这样做是否合理?

// A metafunction to map T -> T but std::reference_wrapper<T> -> T&:
template <typename T> struct RefWrapperToRef { using type = T; };
template <typename T> struct RefWrapperToRef<std::reference_wrapper<T>> { using type = T&; };

// A metafunction like std::remove_reference but std::reference_wrapper<T> -> T.
template <typename T> struct RemoveRefAndRefWrapper {
    using type = std::remove_reference_t<typename RefWrapperToRef<T>::type>;
};

template <typename T>
struct S {
    static_assert(not std::is_rvalue_reference_v<T>, "There may be a place for it, but it's dangerous.");
    T x;

    // Allow construction from a universal reference by forwarding.
    template <typename U>
    explicit S(U&& x) : x(std::forward<U>(x)) {
        static_assert(std::is_same_v<std::remove_cv_t<typename RemoveRefAndRefWrapper<U>::type>,
                                     std::remove_cv_t<typename RemoveRefAndRefWrapper<T>::type>>);
        static_assert(not std::is_reference_v<T> or std::is_lvalue_reference_v<typename RefWrapperToRef<U>::type>);
    }
};

template <typename T>
S(T) -> S<typename RefWrapperToRef<T>::type>;

也就是说,如果你有int x并且打电话S(std::ref(x)),我们会假设你想要一个S<int&>. 这看起来优雅、简单、明确,但又有点神奇。

https://godbolt.org/z/r7KqGKnsf

4

0 回答 0