c++c++20stdc++-concepts

Why no compile error for `std::reference_wrapper<void>` in C++20?


#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!    
}

Now since C++20 has concepts to restrict the class template parameters, and void is not valid for std::reference_wrapper:

Why no compile error for std::reference_wrapper<void> in C++20?


Solution

  • Because no one has written the concept requires (!std::is_void_v<T>) for std::reference_wrapper. I agree, void should not be valid for std::reference_wrapper, and allowing void is probably an oversight from the standard.

    You would think that std::reference_wrapper<void> wouldn't compile anyway, as void& isn't legal. But std::reference_wrapper uses pointers under the covers instead of references, and void* is a perfectly legal pointer, which is why std::reference_wrapper<void> compiles.