std::decay 和传值有什么区别?

问题描述 投票:0回答:2

N4296
std::decay的规格留下了以下注释:

[注:这个 行为类似于 左值到右值 (4.1), 数组到指针(4.2),以及 函数到指针 (4.3) 的转换 当左值表达式为 用作右值,但也剥离 类类型中的 cv 限定符 按顺序 更紧密地按价值建模 参数传递。 — 尾注]

在我看来,理想情况下

std::decay
会模型按值参数传递完全,但由于某种原因它没有这样定义。

我认为它可以根据模板参数推导来定义,在这种情况下,还可以定义实现来利用模板参数推导来精确地模型按值参数传递。

template <typename T>
struct decay {
  private:

  template <typename U>
  static U impl(U);

  public:

  using type = decltype(impl(std::declval<T>()));
};

问题:

  1. std::decay
    和按值参数传递有什么区别?
  2. std::decay
    设计不精确传递按值参数模型吗?
  3. 上面的实现能够准确地模拟它吗?
c++ c++11
2个回答
8
投票

std::decay
是在 N2069 中提出的,激励示例是
std::make_pair
返回一对
decay
-ed 类型,这非常接近
std::make_pair
在 C++11 中的实现方式(有一个
reference_wrapper
略有例外)。请注意该提案最初没有删除 cv 限定符或顶级参考 - 我认为这只是一个疏忽。

至于它只是简单地models按值参数传递而不是duplicates它的原因,我只能猜测可能是后者限制太多。考虑:

struct A {
    A(const A& ) = delete;
};

using T1 = std::decay<A>::type; // T1 == A
using T2 = your_decay<A>::type; // compile error
                                // use of deleted function A(const A&)

我不能说它是否以这种方式明确指定以允许

decay
-ing 不可复制类型 - 但允许其编译似乎是更好的设计。


0
投票

正如 Barry 指出的,不可复制对象存在一个问题。为了解决这个问题,我们可以这样写:

template<typename t>
struct decay {
    template<typename type> static const type& lref() ;
    template<typename u> struct _type_c{ using type = u; };
    template<typename u> static constexpr auto impl(const u&) {
        return _type_c<u>{};
    }
    template<typename u, auto sz> static constexpr auto impl(const u(&)[sz]) {
        return _type_c<u*>{};
    }
    template<typename r, typename... p> static constexpr auto impl(r(&)(p...)) {
        return _type_c<r(*)(p...)>{};
    }
    using type = typename decltype(impl(lref<t>()))::type;
};

它适用于 C++14,不需要任何包含。

衰减还需要从数组引用创建指针和从函数引用创建指针。

© www.soinside.com 2019 - 2024. All rights reserved.