【问题标题】:Why no compile error for `std::reference_wrapper<void>` in C++20?为什么 C++20 中的 `std::reference_wrapper<void>` 没有编译错误?
【发布时间】:2021-07-04 07:08:21
【问题描述】:
#include <functional>
#include <type_traits>

template<typename T>
requires (!std::is_void_v<T>)
struct A {};

int main()
{    
    A<void>*                      p1{}; // compile error as expected.
    std::reference_wrapper<void>* p2{}; // no expected compile error!    
}

现在由于C++20有concepts限制类模板参数,而voidstd::reference_wrapper无效:

为什么在 C++20 中 std::reference_wrapper&lt;void&gt; 没有编译错误?

【问题讨论】:

  • "void 对 std::reference_wrapper 无效" 我在标准中找不到这个。约束应用于构造函数,而不是类型本身。
  • 为什么 C++20 标准没有明确要求 voidstd::reference_wrapper 无效?
  • 如果猜测是因为血液的引用包装器不会造成任何真正的危害,并且允许更简单的模板化代码来处理可能有或可能没有返回类型的函数
  • 我认为这是因为 void 指针是唯一可以用来指向对象的指针。这是任何其他类型都不可能的。

标签: c++ c++20 c++-standard-library c++-concepts


【解决方案1】:

因为没有人为std::reference_wrapper 写过requires (!std::is_void_v&lt;T&gt;) 的概念。我同意,void 不应该对 std::reference_wrapper 有效,而允许 void 可能是对标准的疏忽。

你会认为std::reference_wrapper&lt;void&gt; 无论如何都不会编译,因为void&amp; 是不合法的。但是std::reference_wrapper 在幕后使用指针 而不是引用,而void* 是一个完全合法的指针,这就是std::reference_wrapper&lt;void&gt; 编译的原因。

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 2019-01-15
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2017-03-18
    • 2012-04-20
    相关资源
    最近更新 更多