有没有办法使用概念来禁用会产生对 void 的引用的成员函数?

Is there a way to use concepts to disable member functions that would produce a reference to void?

我希望可以这样写 class

template <class T>
struct A {
    T& operator*() 
        requires (!std::is_void_v<T>)
    {
        return *ptr;
    }
    T* ptr;
};

但是如果我写

A<void> a;

我收到编译器错误

prog.cc: In instantiation of 'struct A<void>':
prog.cc:16:13:   required from here
prog.cc:5:8: error: forming reference to void
    5 |     T& operator*()
      |        ^~~~~~~~

即使 requires 子句禁用了该功能。

有什么方法可以编写 class 以便编译器可以接受禁用的方法吗?

(我知道我可以将 A 部分特化为 void 但这不太方便)。

不,很遗憾,这是不可能的。我希望你写的真的有用,如果有的话,这将是正确的写法,但你就是做不到。

您的选择是:

template <class T>
struct A {
    // #1: a type trait that handles void for you
    std::add_lvalue_reference_t<T> operator*() requires (!std::is_void_v<T>);

    // #2: make it a template (with only one valid instantiation)
    template <std::same_as<T> U=T>
        requires (!std::is_void_v<U>)
    U& operator*();

    // #3: use auto, even though we know the type and it's easy to spell
    auto& operator*() requires (!std::is_void_v<T>);
};

我不喜欢他们三个。您的里程可能会有所不同。